From fe5aff692d3fcceb68ccddf39d1e08c069a6c223 Mon Sep 17 00:00:00 2001 From: Jeremias Menichelli Date: Tue, 21 Jul 2026 12:17:05 +0200 Subject: [PATCH] feat: Add deployment/ci federated content and data (#48041) --- apps/docs/.gitignore | 1 + .../guides/deployment/ci/[[...slug]]/page.tsx | 26 ++++ .../app/guides/deployment/ci/[slug]/page.tsx | 134 ------------------ .../fetch-federated-content.ts | 2 + .../scripts/federated-content/sources/ci.ts | 46 ++++++ apps/docs/scripts/federated-content/types.ts | 2 + 6 files changed, 77 insertions(+), 134 deletions(-) create mode 100644 apps/docs/app/guides/deployment/ci/[[...slug]]/page.tsx delete mode 100644 apps/docs/app/guides/deployment/ci/[slug]/page.tsx create mode 100644 apps/docs/scripts/federated-content/sources/ci.ts diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore index f27e7906398..fd14b1c048b 100644 --- a/apps/docs/.gitignore +++ b/apps/docs/.gitignore @@ -46,6 +46,7 @@ public/docs/ /content/guides/graphql.mdx /content/guides/deployment/terraform.mdx /content/guides/deployment/terraform/tutorial.mdx +/content/guides/deployment/ci/ # Downloaded TypeDoc dumps under spec/reference///. Regenerated by # `cd apps/docs/spec && make download.tsdoc.v2`. Hand-authored files in the diff --git a/apps/docs/app/guides/deployment/ci/[[...slug]]/page.tsx b/apps/docs/app/guides/deployment/ci/[[...slug]]/page.tsx new file mode 100644 index 00000000000..06c603390fb --- /dev/null +++ b/apps/docs/app/guides/deployment/ci/[[...slug]]/page.tsx @@ -0,0 +1,26 @@ +import { GuideTemplate } from '~/features/docs/GuidesMdx.template' +import { + genGuideMeta, + genGuidesStaticParams, + getGuidesMarkdown, +} from '~/features/docs/GuidesMdx.utils' +import { getEmptyArray } from '~/features/helpers.fn' +import { IS_DEV } from '~/lib/constants' + +type Params = { slug?: string[] } + +const ActionDocs = async (props: { params: Promise }) => { + const params = await props.params + const slug = ['deployment', 'ci', ...(params.slug ?? [])] + const data = await getGuidesMarkdown(slug) + + return +} + +const generateStaticParams = !IS_DEV ? genGuidesStaticParams('deployment/ci') : getEmptyArray +const generateMetadata = genGuideMeta((params: { slug?: string[] }) => + getGuidesMarkdown(['deployment', 'ci', ...(params.slug ?? [])]) +) + +export default ActionDocs +export { generateStaticParams, generateMetadata } diff --git a/apps/docs/app/guides/deployment/ci/[slug]/page.tsx b/apps/docs/app/guides/deployment/ci/[slug]/page.tsx deleted file mode 100644 index 4053787f65e..00000000000 --- a/apps/docs/app/guides/deployment/ci/[slug]/page.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { notFound } from 'next/navigation' -import { relative } from 'node:path' -import rehypeSlug from 'rehype-slug' - -import { GuideTemplate, newEditLink } from '~/features/docs/GuidesMdx.template' -import { genGuideMeta, removeRedundantH1 } from '~/features/docs/GuidesMdx.utils' -import { getGitHubFileContents } from '~/lib/octokit' -import { UrlTransformFunction, linkTransform } from '~/lib/mdx/plugins/rehypeLinkTransform' -import remarkMkDocsAdmonition from '~/lib/mdx/plugins/remarkAdmonition' -import { removeTitle } from '~/lib/mdx/plugins/remarkRemoveTitle' -import remarkPyMdownTabs from '~/lib/mdx/plugins/remarkTabs' -import { SerializeOptions } from '~/types/next-mdx-remote-serialize' - -export const dynamicParams = false - -// We fetch these docs at build time from an external repo -const org = 'supabase' -const repo = 'setup-cli' -const branch = 'gh-pages' -const docsDir = 'docs' -const externalSite = 'https://supabase.github.io/setup-cli' - -// Each external docs page is mapped to a local page -const pageMap = [ - { - slug: 'generating-types', - meta: { - title: 'Generate types using GitHub Actions', - description: 'End-to-end type safety across client, server, and database.', - subtitle: 'End-to-end type safety across client, server, and database.', - tocVideo: 'VSNgAIObBdw', - }, - remoteFile: 'generating-types.md', - }, - { - slug: 'testing', - meta: { - title: 'Automated testing using GitHub Actions', - description: 'Run your tests when you or your team make changes.', - subtitle: 'Run your tests when you or your team make changes.', - }, - remoteFile: 'testing.md', - }, - { - slug: 'backups', - meta: { - title: 'Automated backups using GitHub Actions', - description: 'Backup your database on a regular basis.', - subtitle: 'Backup your database on a regular basis.', - }, - remoteFile: 'backups.md', - }, -] - -type Params = { slug: string } - -const ActionDocs = async (props: { params: Promise }) => { - const params = await props.params - const { meta, ...data } = await getContent(params) - - const options = { - mdxOptions: { - remarkPlugins: [remarkMkDocsAdmonition, remarkPyMdownTabs, [removeTitle, meta.title]], - rehypePlugins: [[linkTransform, urlTransform], rehypeSlug], - }, - } as SerializeOptions - - return -} - -/** - * Fetch markdown from external repo - */ -const getContent = async ({ slug }: Params) => { - const page = pageMap.find(({ slug: validSlug }) => validSlug && validSlug === slug) - - if (!page) { - notFound() - } - - const { remoteFile, meta } = page - - const editLink = newEditLink(`${org}/${repo}/blob/${branch}/${docsDir}/${remoteFile}`) - - const content = removeRedundantH1( - await getGitHubFileContents({ org, repo, path: `${docsDir}/${remoteFile}`, branch }) - ) - - return { - pathname: `/guides/deployment/ci/${slug}` satisfies `/${string}`, - meta, - content, - editLink, - } -} - -const urlTransform: UrlTransformFunction = (url) => { - try { - const externalSiteUrl = new URL(externalSite) - - const placeholderHostname = 'placeholder' - const { hostname, pathname, hash } = new URL(url, `http://${placeholderHostname}`) - - // Don't modify a url with a FQDN or a url that's only a hash - if (hostname !== placeholderHostname || pathname === '/') { - return url - } - - const relativePage = ( - pathname.endsWith('.md') - ? pathname.replace(/\.md$/, '') - : relative(externalSiteUrl.pathname, pathname) - ).replace(/^\//, '') - - const page = pageMap.find(({ remoteFile }) => `${relativePage}.md` === remoteFile) - - // If we have a mapping for this page, use the mapped path - if (page) { - return page.slug + hash - } - - // If we don't have this page in our docs, link to original docs - return `${externalSite}/${relativePage}${hash}` - } catch (err) { - console.error('Error transforming markdown URL', err) - return url - } -} - -const generateStaticParams = () => pageMap.map(({ slug }) => ({ slug })) -const generateMetadata = genGuideMeta(getContent) - -export default ActionDocs -export { generateMetadata, generateStaticParams } diff --git a/apps/docs/scripts/federated-content/fetch-federated-content.ts b/apps/docs/scripts/federated-content/fetch-federated-content.ts index 50b8e10bdd4..23f19a912c7 100644 --- a/apps/docs/scripts/federated-content/fetch-federated-content.ts +++ b/apps/docs/scripts/federated-content/fetch-federated-content.ts @@ -125,6 +125,8 @@ async function fetchPage(source: FederatedContentSource, page: FederatedPage): P editLink: `${source.org}/${source.repo}/blob/${source.branch}/${remotePath(source, page)}`, } if (page.meta.subtitle) frontmatter.subtitle = page.meta.subtitle + if (page.meta.description) frontmatter.description = page.meta.description + if (page.meta.tocVideo) frontmatter.tocVideo = page.meta.tocVideo return matter.stringify(`${content}\n`, frontmatter) } diff --git a/apps/docs/scripts/federated-content/sources/ci.ts b/apps/docs/scripts/federated-content/sources/ci.ts new file mode 100644 index 00000000000..a7a8cefc803 --- /dev/null +++ b/apps/docs/scripts/federated-content/sources/ci.ts @@ -0,0 +1,46 @@ +import type { FederatedContentSource } from '../types' + +// We fetch these docs at build time from an external repo +const ci: FederatedContentSource = { + section: 'deployment/ci', + org: 'supabase', + repo: 'setup-cli', + branch: 'gh-pages', + docsDir: 'docs', + externalSite: 'https://supabase.github.io/setup-cli', + pageMap: [ + { + slug: 'generating-types', + meta: { + title: 'Generate types using GitHub Actions', + description: 'End-to-end type safety across client, server, and database.', + subtitle: 'End-to-end type safety across client, server, and database.', + tocVideo: 'VSNgAIObBdw', + }, + remoteFile: 'generating-types.md', + dropLeadingHeading: true, + }, + { + slug: 'testing', + meta: { + title: 'Automated testing using GitHub Actions', + description: 'Run your tests when you or your team make changes.', + subtitle: 'Run your tests when you or your team make changes.', + }, + remoteFile: 'testing.md', + dropLeadingHeading: true, + }, + { + slug: 'backups', + meta: { + title: 'Automated backups using GitHub Actions', + description: 'Backup your database on a regular basis.', + subtitle: 'Backup your database on a regular basis.', + }, + remoteFile: 'backups.md', + dropLeadingHeading: true, + }, + ], +} + +export default ci diff --git a/apps/docs/scripts/federated-content/types.ts b/apps/docs/scripts/federated-content/types.ts index d6a2bee2afd..34470d5f56d 100644 --- a/apps/docs/scripts/federated-content/types.ts +++ b/apps/docs/scripts/federated-content/types.ts @@ -7,6 +7,8 @@ export interface FederatedPage { meta: { title: string subtitle?: string + description?: string + tocVideo?: string } /** Path of the file in the remote repo, relative to `docsDir`. */ remoteFile: string