diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c2fc266790..e42cc70e91 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -66,6 +66,12 @@ jobs: uses: ./.github/workflows/production-build.yml secrets: inherit + build-without-database: + name: Production build (without database) + needs: env + uses: ./.github/workflows/production-build-without-database.yml + secrets: inherit + e2e: name: E2E tests needs: [changes, lint, build] diff --git a/.github/workflows/production-build-without-database.yml b/.github/workflows/production-build-without-database.yml new file mode 100644 index 0000000000..8f2891c278 --- /dev/null +++ b/.github/workflows/production-build-without-database.yml @@ -0,0 +1,17 @@ +name: Production Build (without database) + +on: + workflow_call: + +jobs: + build: + name: Build + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/dangerous-git-checkout + - uses: ./.github/actions/yarn-install + - uses: ./.github/actions/env-read-file + - uses: ./.github/actions/cache-db + - uses: ./.github/actions/cache-build diff --git a/apps/web/pages/apps/[slug]/index.tsx b/apps/web/pages/apps/[slug]/index.tsx index 97a36bf74c..e50c1c061c 100644 --- a/apps/web/pages/apps/[slug]/index.tsx +++ b/apps/web/pages/apps/[slug]/index.tsx @@ -1,3 +1,4 @@ +import { Prisma } from "@prisma/client"; import fs from "fs"; import matter from "gray-matter"; import MarkdownIt from "markdown-it"; @@ -88,8 +89,18 @@ function SingleAppPage(props: inferSSRProps) { } export const getStaticPaths: GetStaticPaths<{ slug: string }> = async () => { - const appStore = await prisma.app.findMany({ select: { slug: true } }); - const paths = appStore.map(({ slug }) => ({ params: { slug } })); + let paths: { params: { slug: string } }[] = []; + + try { + const appStore = await prisma.app.findMany({ select: { slug: true } }); + paths = appStore.map(({ slug }) => ({ params: { slug } })); + } catch (e: unknown) { + if (e instanceof Prisma.PrismaClientInitializationError) { + // Database is not available at build time, but that's ok – we fall back to resolving paths on demand + } else { + throw e; + } + } return { paths, diff --git a/apps/web/pages/apps/categories/[category].tsx b/apps/web/pages/apps/categories/[category].tsx index 80e1bd9e1c..0d80c0002d 100644 --- a/apps/web/pages/apps/categories/[category].tsx +++ b/apps/web/pages/apps/categories/[category].tsx @@ -1,3 +1,4 @@ +import { Prisma } from "@prisma/client"; import type { GetStaticPropsContext, InferGetStaticPropsType } from "next"; import Link from "next/link"; import { useRouter } from "next/router"; @@ -54,6 +55,20 @@ Apps.PageWrapper = PageWrapper; export const getStaticPaths = async () => { const paths = Object.keys(AppCategories); + try { + await prisma.$queryRaw`SELECT 1`; + } catch (e: unknown) { + if (e instanceof Prisma.PrismaClientInitializationError) { + // Database is not available at build time. Make sure we fall back to building these pages on demand + return { + paths: [], + fallback: "blocking", + }; + } else { + throw e; + } + } + return { paths: paths.map((category) => ({ params: { category } })), fallback: false, diff --git a/apps/web/pages/apps/categories/index.tsx b/apps/web/pages/apps/categories/index.tsx index ec0f5ec22d..936e98804b 100644 --- a/apps/web/pages/apps/categories/index.tsx +++ b/apps/web/pages/apps/categories/index.tsx @@ -1,15 +1,19 @@ -import type { InferGetStaticPropsType } from "next"; +import type { GetServerSidePropsContext } from "next"; import Link from "next/link"; -import { getAppRegistry } from "@calcom/app-store/_appRegistry"; +import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry"; +import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import Shell from "@calcom/features/shell/Shell"; import { useLocale } from "@calcom/lib/hooks/useLocale"; +import type { inferSSRProps } from "@calcom/types/inferSSRProps"; import { SkeletonText } from "@calcom/ui"; import { ArrowLeft, ArrowRight } from "@calcom/ui/components/icon"; import PageWrapper from "@components/PageWrapper"; -export default function Apps({ categories }: InferGetStaticPropsType) { +import { ssrInit } from "@server/lib/ssr"; + +export default function Apps({ categories }: inferSSRProps) { const { t, isLocaleReady } = useLocale(); return ( @@ -47,8 +51,20 @@ export default function Apps({ categories }: InferGetStaticPropsType { - const appStore = await getAppRegistry(); +export const getServerSideProps = async (context: GetServerSidePropsContext) => { + const { req, res } = context; + + const ssr = await ssrInit(context); + + const session = await getServerSession({ req, res }); + + let appStore; + if (session?.user?.id) { + appStore = await getAppRegistryWithCredentials(session.user.id); + } else { + appStore = await getAppRegistry(); + } + const categories = appStore.reduce((c, app) => { for (const category of app.categories) { c[category] = c[category] ? c[category] + 1 : 1; @@ -59,6 +75,7 @@ export const getStaticProps = async () => { return { props: { categories: Object.entries(categories).map(([name, count]) => ({ name, count })), + trpcState: ssr.dehydrate(), }, }; };