From 75ffdd85bc90a4d0de798f44516f2731952893c2 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 16:25:26 +0200 Subject: [PATCH 01/24] add Dockerfile and stop linting /lib for now --- .eslintrc.cjs | 1 + Dockerfile | 56 ++++++++++++++++++++++++++++++++++ app/api/parseProtocol/route.ts | 0 3 files changed, 57 insertions(+) create mode 100644 Dockerfile delete mode 100644 app/api/parseProtocol/route.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index fd84c1ed..0914da9a 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -25,6 +25,7 @@ const config = { 'plugin:storybook/recommended', 'prettier', ], + ignorePatterns: ['node_modules', 'lib'], rules: { 'no-process-env': 'error', 'no-console': 'error', diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..988ed3fd --- /dev/null +++ b/Dockerfile @@ -0,0 +1,56 @@ +FROM node:18-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json pnpm-lock.yaml ./ + +# Install pnpm +RUN npm install -g pnpm + +COPY . . + +# Install dependencies using pnpm +RUN pnpm install + +# Rebuild the source code only when needed +FROM base AS builder +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +RUN npm install -g pnpm + +RUN pnpm -v + +RUN pnpm run build + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV production + +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public +COPY --from=builder /app/package.json ./package.json +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT 3000 + +CMD ["node", "server.js"] \ No newline at end of file diff --git a/app/api/parseProtocol/route.ts b/app/api/parseProtocol/route.ts deleted file mode 100644 index e69de29b..00000000 From 7392b728c583ccaa3cb1c8e01802c39441249592 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 18:27:46 +0200 Subject: [PATCH 02/24] fix all linting errors --- .eslintrc.cjs | 2 +- .../dashboard/_actions/importProtocol.ts | 2 +- .../InterviewsTable/InterviewsTable.tsx | 15 ++-- .../_components/InterviewsTable/Loader.ts | 26 ------- .../dashboard/_components/NavigationBar.tsx | 2 +- .../ParticipantsTable/ParticipantsTable.tsx | 1 + .../_components/ProtocolUploader.tsx | 4 +- .../_components/ProtocolsTable/Columns.tsx | 2 +- .../_components/ProtocolsTable/Loader.ts | 22 ------ .../ProtocolsTable/ProtocolsTable.tsx | 12 ++- .../_components/ColumnSelectField.tsx | 2 +- .../_components/DropzoneField.tsx | 3 +- .../_components/ExportCSVParticipants.tsx | 1 + .../interview/[[...interview]]/page.tsx | 36 ++++----- app/(interview)/interview/error.tsx | 7 +- app/(interview)/interview/new/page.tsx | 1 + app/(onboard)/_components/SignUpForm.tsx | 2 +- app/(onboard)/signin/page.tsx | 4 +- components/DataTable/ActionsDropdown.tsx | 10 +-- components/DataTable/DataTable.tsx | 5 +- components/ui/alert-dialog.tsx | 1 + components/ui/dialog.tsx | 3 +- providers/NetworkProvider.tsx | 77 +++++++++++++------ server/routers/protocol.ts | 7 ++ 24 files changed, 124 insertions(+), 123 deletions(-) delete mode 100644 app/(dashboard)/dashboard/_components/InterviewsTable/Loader.ts delete mode 100644 app/(dashboard)/dashboard/_components/ProtocolsTable/Loader.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 0914da9a..ff064ce3 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -25,7 +25,7 @@ const config = { 'plugin:storybook/recommended', 'prettier', ], - ignorePatterns: ['node_modules', 'lib'], + ignorePatterns: ['node_modules', 'lib', '*.stories.*', '*.test.*'], rules: { 'no-process-env': 'error', 'no-console': 'error', diff --git a/app/(dashboard)/dashboard/_actions/importProtocol.ts b/app/(dashboard)/dashboard/_actions/importProtocol.ts index 399aede9..53b27912 100644 --- a/app/(dashboard)/dashboard/_actions/importProtocol.ts +++ b/app/(dashboard)/dashboard/_actions/importProtocol.ts @@ -57,7 +57,7 @@ export const uploadProtocolAssets = async (protocol: NCProtocol, zip: Zip) => { const file = new Blob([blob], { type: `application/${fileExtension}`, - }) as FileEsque; + }) as File; data.append('files', file, `${asset.id}.${fileExtension}`); }), diff --git a/app/(dashboard)/dashboard/_components/InterviewsTable/InterviewsTable.tsx b/app/(dashboard)/dashboard/_components/InterviewsTable/InterviewsTable.tsx index ee5473df..d6d18121 100644 --- a/app/(dashboard)/dashboard/_components/InterviewsTable/InterviewsTable.tsx +++ b/app/(dashboard)/dashboard/_components/InterviewsTable/InterviewsTable.tsx @@ -47,14 +47,13 @@ export const InterviewsTable = () => { columns={InterviewColumns(handleDelete)} data={convertedData} filterColumnAccessorKey="id" - handleDeleteSelected={(data: InterviewWithoutNetwork[]) => { - deleteInterviews(data) - .then((result) => { - if (result.error) throw new Error(result.error); - }) - .catch((error) => { - console.error(error); - }); + handleDeleteSelected={async (data: InterviewWithoutNetwork[]) => { + try { + await deleteInterviews(data); + } catch (error) { + // eslint-disable-next-line no-console + console.error(error); + } }} /> ); diff --git a/app/(dashboard)/dashboard/_components/InterviewsTable/Loader.ts b/app/(dashboard)/dashboard/_components/InterviewsTable/Loader.ts deleted file mode 100644 index c17b034f..00000000 --- a/app/(dashboard)/dashboard/_components/InterviewsTable/Loader.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { prisma } from '~/utils/db'; -import { safeLoader } from '~/utils/safeLoader'; -import { z } from 'zod'; - -const InterviewValidation = z.array( - z.object({ - id: z.string(), - startTime: z.date(), - finishTime: z.date().nullable(), - exportTime: z.date().nullable(), - lastUpdated: z.date(), - protocolId: z.string(), - currentStep: z.number(), - network: z.string(), - }), -); - -export const safeLoadInterviews = safeLoader({ - outputValidation: InterviewValidation, - loader: () => - prisma.interview.findMany({ - include: { - protocol: true, - }, - }), -}); diff --git a/app/(dashboard)/dashboard/_components/NavigationBar.tsx b/app/(dashboard)/dashboard/_components/NavigationBar.tsx index 46719785..fa279b78 100644 --- a/app/(dashboard)/dashboard/_components/NavigationBar.tsx +++ b/app/(dashboard)/dashboard/_components/NavigationBar.tsx @@ -6,7 +6,7 @@ import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { cn } from '~/utils/shadcn'; import UserMenu from './UserMenu'; -import { UrlObject } from 'url'; +import type { UrlObject } from 'url'; export const NavButton = ({ children, diff --git a/app/(dashboard)/dashboard/_components/ParticipantsTable/ParticipantsTable.tsx b/app/(dashboard)/dashboard/_components/ParticipantsTable/ParticipantsTable.tsx index fb395c14..99620ce8 100644 --- a/app/(dashboard)/dashboard/_components/ParticipantsTable/ParticipantsTable.tsx +++ b/app/(dashboard)/dashboard/_components/ParticipantsTable/ParticipantsTable.tsx @@ -28,6 +28,7 @@ export const ParticipantsTable = ({ initialData, refetchOnMount: false, onError(error) { + // eslint-disable-next-line no-console console.error(error); }, }); diff --git a/app/(dashboard)/dashboard/_components/ProtocolUploader.tsx b/app/(dashboard)/dashboard/_components/ProtocolUploader.tsx index 21181794..437e2b83 100644 --- a/app/(dashboard)/dashboard/_components/ProtocolUploader.tsx +++ b/app/(dashboard)/dashboard/_components/ProtocolUploader.tsx @@ -124,6 +124,7 @@ export default function ProtocolUploader({ }); }, onUploadProgress: (file, progress) => { + // eslint-disable-next-line no-console console.log( '🚀 ~ file: ProtocolUploader.tsx:102 ~ ProtocolUploader ~ file>:progress', `${file}>${progress}`, @@ -141,6 +142,7 @@ export default function ProtocolUploader({ }); startUpload([file]).catch((e: Error) => { + // eslint-disable-next-line no-console console.log(e); setOpen(true); setDialogContent({ @@ -223,7 +225,7 @@ export default function ProtocolUploader({ {!dialogContent.progress && !dialogContent.error && (
void form.handleSubmit(onSubmit)} className="w-full space-y-6" >
diff --git a/app/(dashboard)/dashboard/_components/ProtocolsTable/Columns.tsx b/app/(dashboard)/dashboard/_components/ProtocolsTable/Columns.tsx index 07c549ba..11dc09ac 100644 --- a/app/(dashboard)/dashboard/_components/ProtocolsTable/Columns.tsx +++ b/app/(dashboard)/dashboard/_components/ProtocolsTable/Columns.tsx @@ -92,7 +92,7 @@ export const ProtocolColumns: ColumnDef[] = [ ), cell: () => { - return ; + return ; }, }, ]; diff --git a/app/(dashboard)/dashboard/_components/ProtocolsTable/Loader.ts b/app/(dashboard)/dashboard/_components/ProtocolsTable/Loader.ts deleted file mode 100644 index 124b921c..00000000 --- a/app/(dashboard)/dashboard/_components/ProtocolsTable/Loader.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { prisma } from '~/utils/db'; -import { safeLoader } from '~/utils/safeLoader'; -import { z } from 'zod'; - -const ProtocolValidation = z.array( - z.object({ - id: z.string(), - hash: z.string(), - name: z.string(), - schemaVersion: z.number(), - description: z.string(), - assetPath: z.string(), - importedAt: z.date(), - lastModified: z.date(), - stages: z.string(), - }), -); - -export const safeLoadProtocols = safeLoader({ - outputValidation: ProtocolValidation, - loader: () => prisma.protocol.findMany(), -}); diff --git a/app/(dashboard)/dashboard/_components/ProtocolsTable/ProtocolsTable.tsx b/app/(dashboard)/dashboard/_components/ProtocolsTable/ProtocolsTable.tsx index 20ffde5c..0a436ba6 100644 --- a/app/(dashboard)/dashboard/_components/ProtocolsTable/ProtocolsTable.tsx +++ b/app/(dashboard)/dashboard/_components/ProtocolsTable/ProtocolsTable.tsx @@ -1,10 +1,14 @@ import { DataTable } from '~/components/DataTable/DataTable'; -import { ProtocolColumns } from '~/app/(main)/_components/ProtocolsTable/Columns'; -import { safeLoadProtocols } from '~/app/(main)/_components/ProtocolsTable/Loader'; +import { ProtocolColumns } from './Columns'; +import { trpc } from '~/app/_trpc/server'; -const protocols = await safeLoadProtocols(); +export const ProtocolsTable = async () => { + const protocols = await trpc.protocol.get.all.query(undefined, { + context: { + revalidate: 0, + }, + }); -export const ProtocolsTable = () => { return ( + void onDrop(acceptedFiles, fileRejections), }); const componentId = id || name; diff --git a/app/(dashboard)/dashboard/participants/_components/ExportCSVParticipants.tsx b/app/(dashboard)/dashboard/participants/_components/ExportCSVParticipants.tsx index 68dc15b2..66a5785b 100644 --- a/app/(dashboard)/dashboard/participants/_components/ExportCSVParticipants.tsx +++ b/app/(dashboard)/dashboard/participants/_components/ExportCSVParticipants.tsx @@ -39,6 +39,7 @@ function ExportCSVParticipants({ // Clean up the URL object URL.revokeObjectURL(url); } catch (error) { + // eslint-disable-next-line no-console console.error(error); } diff --git a/app/(interview)/interview/[[...interview]]/page.tsx b/app/(interview)/interview/[[...interview]]/page.tsx index ffa68202..5fe58f7a 100644 --- a/app/(interview)/interview/[[...interview]]/page.tsx +++ b/app/(interview)/interview/[[...interview]]/page.tsx @@ -3,7 +3,7 @@ import { NetworkProvider } from '~/providers/NetworkProvider'; import Stage from '~/app/(interview)/interview/_components/Stage'; import { prisma } from '~/utils/db'; import InterviewNavigation from '~/app/(interview)/interview/_components/InterviewNavigation'; -import type { NcNetwork, Stage as StageType } from '@codaco/shared-consts'; +import type { NcNetwork, Protocol } from '@codaco/shared-consts'; import Link from 'next/link'; import { trpc } from '~/app/_trpc/server'; @@ -19,7 +19,14 @@ export default async function Page({ if (!interviewId) { return; } - const interview = await trpc.interview.get.byId.query({ id: interviewId }); + const interview = await trpc.interview.get.byId.query( + { id: interviewId }, + { + context: { + revalidate: 0, + }, + }, + ); if (!interview) { return
No interview found
; @@ -34,27 +41,17 @@ export default async function Page({ } redirect(`/interview/${interviewId}/1`); - - return null; } // Fetch the protocol stage configuration for the current page from the database - const { - network, - protocol: { stages }, - } = interview; - - if (!stages) { - return
No stages found
; - } - - const stagesJson = JSON.parse(stages) as StageType[]; + const network = interview.network as NcNetwork; + const protocol = interview.protocol as unknown as Protocol; + const stages = protocol.stages; - const currentStageConfig = - stagesJson[parseInt(currentInterviewPage!, 10) - 1]; + const currentStageConfig = stages[parseInt(currentInterviewPage!, 10) - 1]; if (!currentStageConfig) { - // redirect(`/interview/${interviewId}/1`); + return
No stage found
; } const updateNetwork = async (network: NcNetwork) => { @@ -78,7 +75,10 @@ export default async function Page({ }; return ( - + void updateNetwork(data)} + >

Interview

Exit interview diff --git a/app/(interview)/interview/error.tsx b/app/(interview)/interview/error.tsx index 3575bbdc..902d6348 100644 --- a/app/(interview)/interview/error.tsx +++ b/app/(interview)/interview/error.tsx @@ -1,7 +1,7 @@ -"use client"; // Error components must be Client components +'use client'; // Error components must be Client components -import { useEffect } from "react"; -import { Button } from "~/components/ui/Button"; +import { useEffect } from 'react'; +import { Button } from '~/components/ui/Button'; export default function Error({ error, @@ -12,6 +12,7 @@ export default function Error({ }) { useEffect(() => { // Log the error to an error reporting service + // eslint-disable-next-line no-console console.error(error); }, [error]); diff --git a/app/(interview)/interview/new/page.tsx b/app/(interview)/interview/new/page.tsx index 1558db39..c0c183a2 100644 --- a/app/(interview)/interview/new/page.tsx +++ b/app/(interview)/interview/new/page.tsx @@ -64,6 +64,7 @@ export default async function Page({ const { createdInterview } = await trpc.interview.create.mutate(identifier); if (!createdInterview) { + // eslint-disable-next-line no-console console.error('Error creating interview'); return; } diff --git a/app/(onboard)/_components/SignUpForm.tsx b/app/(onboard)/_components/SignUpForm.tsx index 0d101dd7..955c8831 100644 --- a/app/(onboard)/_components/SignUpForm.tsx +++ b/app/(onboard)/_components/SignUpForm.tsx @@ -28,7 +28,7 @@ export const SignUpForm = ({ }); const { mutateAsync: signUp, isLoading } = trpc.session.signUp.useMutation({ - onSuccess: async (result) => { + onSuccess: (result) => { if (result.error) { const error = result.error; setSignupError(error); diff --git a/app/(onboard)/signin/page.tsx b/app/(onboard)/signin/page.tsx index 89725317..c14da9d2 100644 --- a/app/(onboard)/signin/page.tsx +++ b/app/(onboard)/signin/page.tsx @@ -1,7 +1,7 @@ import { userFormClasses } from '../_shared'; import SignInForm from '../_components/SignInForm'; import { cn } from '~/utils/shadcn'; -import { redirect } from 'next/navigation'; +import type { Route } from 'next'; export const metadata = { title: 'Fresco - Sign In', @@ -12,7 +12,7 @@ export default function Page({ searchParams, }: { searchParams: { - callbackUrl?: string; + callbackUrl?: Route; }; }) { const { callbackUrl } = searchParams; diff --git a/components/DataTable/ActionsDropdown.tsx b/components/DataTable/ActionsDropdown.tsx index b8b7285a..6f0fb0af 100644 --- a/components/DataTable/ActionsDropdown.tsx +++ b/components/DataTable/ActionsDropdown.tsx @@ -5,7 +5,6 @@ import { Button } from '~/components/ui/Button'; import { DropdownMenu, DropdownMenuContent, - DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger, } from '~/components/ui/dropdown-menu'; @@ -19,7 +18,7 @@ interface Actions { } interface Props { - menuItems: TMenuItem[]; + menuItems?: TMenuItem[]; } export const ActionsDropdown = ({ @@ -35,9 +34,10 @@ export const ActionsDropdown = ({ Actions - {menuItems.map((item, index) => ( - {item.component} - ))} + {menuItems && + menuItems.map((item, index) => ( + {item.component} + ))} ); diff --git a/components/DataTable/DataTable.tsx b/components/DataTable/DataTable.tsx index b54d7e0f..743a6046 100644 --- a/components/DataTable/DataTable.tsx +++ b/components/DataTable/DataTable.tsx @@ -29,7 +29,7 @@ interface DataTableProps { columns?: ColumnDef[]; data: TData[]; filterColumnAccessorKey?: string; - handleDeleteSelected: (data: TData[]) => Promise; + handleDeleteSelected?: (data: TData[]) => Promise; } export function DataTable({ @@ -55,8 +55,9 @@ export function DataTable({ .rows.map((r) => r.original); try { - await handleDeleteSelected(selectedData); + await handleDeleteSelected?.(selectedData); } catch (error) { + // eslint-disable-next-line no-console console.error(error); } diff --git a/components/ui/alert-dialog.tsx b/components/ui/alert-dialog.tsx index 9a7bdb32..3eee4ff9 100644 --- a/components/ui/alert-dialog.tsx +++ b/components/ui/alert-dialog.tsx @@ -21,6 +21,7 @@ AlertDialogPortal.displayName = AlertDialogPrimitive.Portal.displayName; const AlertDialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef + // eslint-disable-next-line @typescript-eslint/no-unused-vars >(({ className, children, ...props }, ref) => ( , React.ComponentPropsWithoutRef + // eslint-disable-next-line @typescript-eslint/no-unused-vars >(({ className, ...props }, ref) => ( )); diff --git a/providers/NetworkProvider.tsx b/providers/NetworkProvider.tsx index 4d10c01d..063fe823 100644 --- a/providers/NetworkProvider.tsx +++ b/providers/NetworkProvider.tsx @@ -7,7 +7,7 @@ import { useEffect, type PropsWithChildren, } from 'react'; -import type { NcNetwork } from '@codaco/shared-consts'; +import type { NcEdge, NcNetwork, NcNode } from '@codaco/shared-consts'; const initialState: NcNetwork = { nodes: [], @@ -15,7 +15,7 @@ const initialState: NcNetwork = { ego: undefined, }; -type NetworkAction = { +type NetworkActionBase = { type: | 'ADD_NODE' | 'ADD_EDGE' @@ -23,9 +23,47 @@ type NetworkAction = { | 'UPDATE_EDGE' | 'DELETE_NODE' | 'DELETE_EDGE'; - payload: Record; + payload: unknown; }; +type ActionAddNode = NetworkActionBase & { + type: 'ADD_NODE'; + payload: NcNode; +}; + +type ActionAddEdge = NetworkActionBase & { + type: 'ADD_EDGE'; + payload: NcEdge; +}; + +type ActionUpdateNode = NetworkActionBase & { + type: 'UPDATE_NODE'; + payload: NcNode; +}; + +type ActionUpdateEdge = NetworkActionBase & { + type: 'UPDATE_EDGE'; + payload: NcEdge; +}; + +type ActionDeleteNode = NetworkActionBase & { + type: 'DELETE_NODE'; + payload: string; +}; + +type ActionDeleteEdge = NetworkActionBase & { + type: 'DELETE_EDGE'; + payload: string; +}; + +type NetworkAction = + | ActionAddNode + | ActionAddEdge + | ActionUpdateNode + | ActionUpdateEdge + | ActionDeleteNode + | ActionDeleteEdge; + function reducer(state: NcNetwork, action: NetworkAction): NcNetwork { switch (action.type) { case 'ADD_NODE': @@ -42,25 +80,25 @@ function reducer(state: NcNetwork, action: NetworkAction): NcNetwork { return { ...state, nodes: state.nodes.map((node) => - node.id === action.payload.id ? action.payload : node, + node._uid === action.payload._uid ? action.payload : node, ), }; case 'UPDATE_EDGE': return { ...state, edges: state.edges.map((edge) => - edge.id === action.payload.id ? action.payload : edge, + edge._uid === action.payload._uid ? action.payload : edge, ), }; case 'DELETE_NODE': return { ...state, - nodes: state.nodes.filter((node) => node.id !== action.payload), + nodes: state.nodes.filter((node) => node._uid !== action.payload), }; case 'DELETE_EDGE': return { ...state, - edges: state.edges.filter((edge) => edge.id !== action.payload), + edges: state.edges.filter((edge) => edge._uid !== action.payload), }; default: return state; @@ -76,25 +114,16 @@ const NetworkContext = createContext({ }); type NetworkProviderProps = { - network: string | null; + network: NcNetwork; updateNetwork: (network: NcNetwork) => void; }; -const getInitialState = (network: string | null): NcNetwork => { - if (network) { - return JSON.parse(network) as NcNetwork; - } - return initialState; -}; - function NetworkProvider({ network, updateNetwork, children, }: PropsWithChildren) { - const [state, dispatch] = useReducer(reducer, initialState, () => - getInitialState(network), - ); + const [state, dispatch] = useReducer(reducer, network); // When state changes, sync it with the server using react query useEffect(() => { @@ -111,27 +140,27 @@ function NetworkProvider({ const useInterview = () => { const { state, dispatch } = useContext(NetworkContext); - const addNode = (node) => { + const addNode = (node: NcNode) => { dispatch({ type: 'ADD_NODE', payload: node }); }; - const addEdge = (edge) => { + const addEdge = (edge: NcEdge) => { dispatch({ type: 'ADD_EDGE', payload: edge }); }; - const updateNode = (node) => { + const updateNode = (node: NcNode) => { dispatch({ type: 'UPDATE_NODE', payload: node }); }; - const updateEdge = (edge) => { + const updateEdge = (edge: NcEdge) => { dispatch({ type: 'UPDATE_EDGE', payload: edge }); }; - const deleteNode = (nodeId) => { + const deleteNode = (nodeId: string) => { dispatch({ type: 'DELETE_NODE', payload: nodeId }); }; - const deleteEdge = (edgeId) => { + const deleteEdge = (edgeId: string) => { dispatch({ type: 'DELETE_EDGE', payload: edgeId }); }; diff --git a/server/routers/protocol.ts b/server/routers/protocol.ts index 2bacfe14..95caf2d0 100644 --- a/server/routers/protocol.ts +++ b/server/routers/protocol.ts @@ -9,6 +9,13 @@ const updateActiveProtocolSchema = z.object({ }); export const protocolRouter = router({ + get: router({ + all: protectedProcedure.query(async () => { + const protocols = await prisma.protocol.findMany(); + + return protocols; + }), + }), getActive: publicProcedure.query(async () => { const activeProtocol = await prisma.protocol.findFirst({ where: { From 33df063d54109f6d0412bd49abe2fac7302c6abb Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 20:16:47 +0200 Subject: [PATCH 03/24] fix all typescript errors --- .../_components/InterviewsTable/Columns.tsx | 13 ++- .../dashboard/_components/NavigationBar.tsx | 5 +- .../interview/_components/Stage.tsx | 18 +++- .../OnboardSteps/ManageParticipants.tsx | 3 +- .../_components/OnboardSteps/StepsSidebar.tsx | 2 +- app/_trpc/server.ts | 2 + components/DataTable/DataTable.tsx | 2 - package.json | 1 + providers/Providers.tsx | 2 + server/trpc.ts | 5 +- stories/Header.tsx | 16 ++-- tailwind.config.ts | 4 +- tsconfig.json | 18 ++-- utils/calculateRedirectedRoutes.ts | 2 +- utils/generateMockData/interview/interview.ts | 2 +- utils/generateMockData/protocol/protocol.ts | 7 +- utils/generateMockData/team.ts | 14 ---- utils/uploadthing/useFetch.ts | 2 +- utils/validateProtocol.ts | 83 ------------------- 19 files changed, 68 insertions(+), 133 deletions(-) delete mode 100644 utils/generateMockData/team.ts delete mode 100644 utils/validateProtocol.ts diff --git a/app/(dashboard)/dashboard/_components/InterviewsTable/Columns.tsx b/app/(dashboard)/dashboard/_components/InterviewsTable/Columns.tsx index 5f99ecab..9b1901c2 100644 --- a/app/(dashboard)/dashboard/_components/InterviewsTable/Columns.tsx +++ b/app/(dashboard)/dashboard/_components/InterviewsTable/Columns.tsx @@ -13,6 +13,8 @@ import { TooltipTrigger, } from '~/components/ui/tooltip'; import { Settings } from 'lucide-react'; +import { Button } from '~/components/ui/Button'; +import { DropdownMenuItem } from '~/components/ui/dropdown-menu'; type InterviewWithoutNetwork = Omit; @@ -139,9 +141,14 @@ export const InterviewColumns = ( menuItems={[ { label: 'Delete', - id: row.original.id, - idendtifier: row.original.id, - deleteItem: handleDelete, + row, + component: ( + void handleDelete(row.original.id)} + > + Edit + + ), }, ]} /> diff --git a/app/(dashboard)/dashboard/_components/NavigationBar.tsx b/app/(dashboard)/dashboard/_components/NavigationBar.tsx index fa279b78..c10aebfb 100644 --- a/app/(dashboard)/dashboard/_components/NavigationBar.tsx +++ b/app/(dashboard)/dashboard/_components/NavigationBar.tsx @@ -7,6 +7,7 @@ import { usePathname } from 'next/navigation'; import { cn } from '~/utils/shadcn'; import UserMenu from './UserMenu'; import type { UrlObject } from 'url'; +import type { Route } from 'next'; export const NavButton = ({ children, @@ -14,7 +15,7 @@ export const NavButton = ({ isActive = false, }: { children: React.ReactNode; - href: UrlObject; + href: UrlObject | Route; isActive?: boolean; }) => { return ( @@ -51,7 +52,7 @@ export function NavigationBar() { Home Protocols diff --git a/app/(interview)/interview/_components/Stage.tsx b/app/(interview)/interview/_components/Stage.tsx index d4ffbb97..dabd52f7 100644 --- a/app/(interview)/interview/_components/Stage.tsx +++ b/app/(interview)/interview/_components/Stage.tsx @@ -1,7 +1,11 @@ 'use client'; import { useInterview } from '~/providers/NetworkProvider'; -import { Stage } from '@codaco/shared-consts'; +import { + Stage, + entityAttributesProperty, + entityPrimaryKeyProperty, +} from '@codaco/shared-consts'; import Button from '@codaco/ui/lib/components/Button'; import { v4 as uuid } from 'uuid'; @@ -30,7 +34,17 @@ const Stage = ({ stageConfig }: { stageConfig: Stage }) => {
-
diff --git a/app/(onboard)/_components/OnboardSteps/ManageParticipants.tsx b/app/(onboard)/_components/OnboardSteps/ManageParticipants.tsx index 5103d1ff..4155c971 100644 --- a/app/(onboard)/_components/OnboardSteps/ManageParticipants.tsx +++ b/app/(onboard)/_components/OnboardSteps/ManageParticipants.tsx @@ -4,9 +4,10 @@ import ProtocolUploader from '~/app/(dashboard)/dashboard/_components/ProtocolUp import { Button } from '~/components/ui/Button'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; import AnonymousRecruitmentSwitch from '~/app/(dashboard)/dashboard/_components/AnonymousRecruitmentSwitch'; +import type { Route } from 'next'; function ManageParticipants() { - const pathname = usePathname(); + const pathname = usePathname() as Route; const searchParams = useSearchParams(); const currentStep = searchParams.get('step') as string; const [participantsUploaded, setParticipantsUploaded] = useState(false); diff --git a/app/(onboard)/_components/OnboardSteps/StepsSidebar.tsx b/app/(onboard)/_components/OnboardSteps/StepsSidebar.tsx index ea361699..42eee7f1 100644 --- a/app/(onboard)/_components/OnboardSteps/StepsSidebar.tsx +++ b/app/(onboard)/_components/OnboardSteps/StepsSidebar.tsx @@ -46,7 +46,7 @@ function OnboardSteps({ currentStep }: { currentStep: keyof typeof steps }) { number={index} description={stepItem.description} active={index === currentStep} - complete={index < currentStep} + complete={index < Number(currentStep)} /> ))}
diff --git a/app/_trpc/server.ts b/app/_trpc/server.ts index ca24c755..d18cc5e0 100644 --- a/app/_trpc/server.ts +++ b/app/_trpc/server.ts @@ -4,6 +4,7 @@ import { loggerLink } from '@trpc/client'; import { experimental_nextHttpLink } from '@trpc/next/app-dir/links/nextHttp'; import { experimental_createTRPCNextAppDirServer } from '@trpc/next/app-dir/server'; import { cookies } from 'next/headers'; +import SuperJSON from 'superjson'; import { env } from '~/env.mjs'; import { type AppRouter } from '~/server/router'; import { getUrl } from '~/utils/getURL'; @@ -14,6 +15,7 @@ import { getUrl } from '~/utils/getURL'; export const trpc = experimental_createTRPCNextAppDirServer({ config() { return { + transformer: SuperJSON, links: [ loggerLink({ enabled: (opts) => diff --git a/components/DataTable/DataTable.tsx b/components/DataTable/DataTable.tsx index 743a6046..ad3459b0 100644 --- a/components/DataTable/DataTable.tsx +++ b/components/DataTable/DataTable.tsx @@ -10,7 +10,6 @@ import { type SortingState, } from '@tanstack/react-table'; import { useState } from 'react'; - import { Button } from '~/components/ui/Button'; import { Input } from '~/components/ui/Input'; import { @@ -21,7 +20,6 @@ import { TableHeader, TableRow, } from '~/components/ui/table'; - import { makeDefaultColumns } from '~/components/DataTable/DefaultColumns'; import { Loader } from 'lucide-react'; diff --git a/package.json b/package.json index 0faf16f2..82c8ca37 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dev": "next dev", "postinstall": "prisma generate && prisma db push", "lint": "next lint", + "ts-lint": "tsc --noEmit --incremental --watch", "start": "next start", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", diff --git a/providers/Providers.tsx b/providers/Providers.tsx index 0d4748e8..091f3fe2 100644 --- a/providers/Providers.tsx +++ b/providers/Providers.tsx @@ -8,6 +8,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { SessionProvider } from '~/providers/SessionPrivider'; import type { Session } from 'lucia'; import { env } from '~/env.mjs'; +import SuperJSON from 'superjson'; export default function Providers({ children, @@ -19,6 +20,7 @@ export default function Providers({ const [queryClient] = useState(() => new QueryClient()); const [trpcClient] = useState(() => trpc.createClient({ + transformer: SuperJSON, links: [ loggerLink({ enabled: (opts) => diff --git a/server/trpc.ts b/server/trpc.ts index a5194cf0..9a2508f7 100644 --- a/server/trpc.ts +++ b/server/trpc.ts @@ -1,8 +1,11 @@ import { TRPCError, initTRPC } from '@trpc/server'; import type { createTRPCContext } from './context'; +import superjson from 'superjson'; import { env } from '~/env.mjs'; -const t = initTRPC.context().create(); +const t = initTRPC.context().create({ + transformer: superjson, +}); const enforceUserIsAuthed = t.middleware(({ ctx, next }) => { if (!ctx.session || !ctx.session?.user) { diff --git a/stories/Header.tsx b/stories/Header.tsx index 6e63c3d8..c7ab80cd 100644 --- a/stories/Header.tsx +++ b/stories/Header.tsx @@ -1,6 +1,5 @@ import React from 'react'; - -import Button from '../ui/components/Button'; +import { Button } from '~/components/ui//Button'; import './header.css'; type User = { @@ -52,17 +51,14 @@ export const Header = ({ Welcome, {user.name}! - ) : ( <> - + )} diff --git a/tailwind.config.ts b/tailwind.config.ts index c2a9b420..26342560 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -57,12 +57,12 @@ export default { }, keyframes: { 'accordion-down': { - from: { height: 0 }, + from: { height: '0' }, to: { height: 'var(--radix-accordion-content-height)' }, }, 'accordion-up': { from: { height: 'var(--radix-accordion-content-height)' }, - to: { height: 0 }, + to: { height: '0' }, }, 'indeterminate-progress-bar': { '0%': { transform: ' translateX(0) scaleX(0)' }, diff --git a/tsconfig.json b/tsconfig.json index a3d45ab8..c6e714aa 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,13 @@ { "compilerOptions": { "target": "es2017", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, - "checkJs": true, + "checkJs": false, "skipLibCheck": true, "strict": true, "forceConsistentCasingInFileNames": true, @@ -18,7 +22,9 @@ "noUncheckedIndexedAccess": true, "baseUrl": ".", "paths": { - "~/*": ["./*"] + "~/*": [ + "./*" + ] }, "plugins": [ { @@ -36,5 +42,7 @@ ".next/types/**/*.ts", "eslint-local-rules/index.js" ], - "exclude": ["node_modules"] -} + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/utils/calculateRedirectedRoutes.ts b/utils/calculateRedirectedRoutes.ts index 401b1d15..e97f4706 100644 --- a/utils/calculateRedirectedRoutes.ts +++ b/utils/calculateRedirectedRoutes.ts @@ -78,7 +78,7 @@ export const calculateRedirect = ({ return; } - return '/signin?callbackUrl=' + encodeURI(path); + return ('/signin?callbackUrl=' + encodeURI(path)) as Route; } // APP IS CONFIGURED AND SESSION EXISTS diff --git a/utils/generateMockData/interview/interview.ts b/utils/generateMockData/interview/interview.ts index 291c4cb5..26d71128 100644 --- a/utils/generateMockData/interview/interview.ts +++ b/utils/generateMockData/interview/interview.ts @@ -4,7 +4,7 @@ import network from './network.json' assert { type: 'json' }; type InterviewUncheckedCreateWithoutProtocolAndUserInput = Omit< Prisma.InterviewUncheckedCreateWithoutProtocolInput, - 'userId' + 'participantId' >; const mockInterview = diff --git a/utils/generateMockData/protocol/protocol.ts b/utils/generateMockData/protocol/protocol.ts index b70e0bc9..8185b6bc 100644 --- a/utils/generateMockData/protocol/protocol.ts +++ b/utils/generateMockData/protocol/protocol.ts @@ -2,16 +2,15 @@ import { faker } from '@faker-js/faker'; import { type Prisma } from '@prisma/client'; import stages from './stages.json' assert { type: 'json' }; -const mockProtocol = (): Prisma.ProtocolUncheckedCreateWithoutOwnerInput => { +const mockProtocol = (): Prisma.ProtocolUncheckedCreateInput => { return { name: faker.word.words(4), hash: faker.word.words(4), + codebook: {}, schemaVersion: faker.number.int({ min: 6, max: 8 }), description: faker.lorem.sentence(), - assetPath: 'assets/path', lastModified: faker.date.past(), - stages: JSON.stringify(stages), - codebook: '{}', + stages: stages, }; }; diff --git a/utils/generateMockData/team.ts b/utils/generateMockData/team.ts deleted file mode 100644 index d4108616..00000000 --- a/utils/generateMockData/team.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { Prisma } from '@prisma/client'; - -const mockTeam = (): Prisma.TeamUncheckedCreateWithoutStudiesInput => { - return { - name: faker.company.name(), - description: faker.company.catchPhrase(), - image: faker.image.url(), - createdAt: faker.date.past(), - updatedAt: faker.date.recent(), - }; -}; - -export default mockTeam; diff --git a/utils/uploadthing/useFetch.ts b/utils/uploadthing/useFetch.ts index c0c909c4..4b13d4be 100644 --- a/utils/uploadthing/useFetch.ts +++ b/utils/uploadthing/useFetch.ts @@ -11,7 +11,7 @@ type Cache = { [url: string]: T }; // discriminated union type type Action = | { type: 'loading' } - | { type: 'fetched'; payload: T } + | { type: 'fetched'; payload: T | undefined } | { type: 'error'; payload: Error }; function useFetch(url?: string, options?: RequestInit): State { diff --git a/utils/validateProtocol.ts b/utils/validateProtocol.ts deleted file mode 100644 index 7f20b50c..00000000 --- a/utils/validateProtocol.ts +++ /dev/null @@ -1,83 +0,0 @@ -import friendlyErrorMessage from './friendlyErrorMessage'; -import { validateSchema, validateLogic } from '../lib/protocol-utils'; -import { errToString } from '../lib/protocol-utils/validate/helpers'; -import { APP_SUPPORTED_SCHEMA_VERSIONS } from '~/fresco.config'; - -const openError = friendlyErrorMessage( - "There was an error reading that protocol file. It doesn't seem to be a valid JSON object. Check the format of your protocol, and try again.", -); -const validationError = friendlyErrorMessage( - 'Your protocol file failed validation. See below for the specific problems we found. This is often caused by attempting to open a protocol file authored in an incompatible version of Architect.', -); - -// Basic validation on protocol format; -// any error will halt loading and display a message to the user. -const validateProtocol = (protocol) => { - // console.log('utils>>>', utils); - // console.log('utils>>>', utils.validateSchema); - // console.log('utils>>>', utils.validateSchema.default); - // const validateSchema = utils.validateSchema.default; - // const validateLogic = utils.validateLogic.default; - // concentricCircles: 3, skewedTowardCenter: true } - - protocol.stages[17].background = { - ...protocol.stages[17].background, - concentricCircles: 3, - skewedTowardCenter: true, - }; - - protocol.stages[29].background = { - ...protocol.stages[29].background, - skewedTowardCenter: true, - }; - const schemaErrors = validateSchema.default(protocol); - // const schemaErrors = []; - // console.log( - // '🚀 ~ file: parseProtocol.ts:24 ~ validateProtocol ~ schemaErrors:', - // schemaErrors, - // ); - // console.log('/stages/17/background>16', protocol.stages[16].background); - // console.log('/stages/17/background>29', protocol.stages[29].background); - // const logicErrors = validateLogic.default(protocol); - const logicErrors = []; - - if (schemaErrors.length > 0 || logicErrors.length > 0) { - throw new Error( - [...schemaErrors, ...logicErrors].map(errToString).join(''), - ); - } -}; - -const checkSchemaVersion = (protocol: any) => { - if (!APP_SUPPORTED_SCHEMA_VERSIONS.includes(protocol.schemaVersion)) { - throw new Error( - 'The schema version of this protocol is not compatible with this version of Network Canvas Interviewer. Upgrade the protocol using Architect, and try importing it again.', - ); - } -}; - -// const parseProtocol1 = (protocolUID, name) => -// readFile(protocolPath(protocolUID, 'protocol.json')) -// .then((json) => JSON.parse(json)) -// .then((protocol) => checkSchemaVersion(protocol)) -// .then((protocol) => validateProtocol(protocol)) -// .catch(validationError) -// .then((protocol) => { -// const withFilename = { -// ...protocol, -// name, -// uid: protocolUID, -// }; -// return withFilename; -// }) -// .catch(openError); - -export default function parseProtocol(protocol: any) { - try { - checkSchemaVersion(protocol); - validateProtocol(protocol); - console.log('protocal parsed'); - } catch (e) { - validationError(e); - } -} From 221f0ab74a7ed425db6c41aa2929809a8f8c4066 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 20:19:55 +0200 Subject: [PATCH 04/24] remove unused import --- .../dashboard/_components/InterviewsTable/Columns.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/(dashboard)/dashboard/_components/InterviewsTable/Columns.tsx b/app/(dashboard)/dashboard/_components/InterviewsTable/Columns.tsx index 9b1901c2..04676a14 100644 --- a/app/(dashboard)/dashboard/_components/InterviewsTable/Columns.tsx +++ b/app/(dashboard)/dashboard/_components/InterviewsTable/Columns.tsx @@ -5,7 +5,6 @@ import type { Interview } from '@prisma/client'; import { ActionsDropdown } from '~/components/DataTable/ActionsDropdown'; import { Checkbox } from '~/components/ui/checkbox'; import { DataTableColumnHeader } from '~/components/DataTable/ColumnHeader'; - import { Tooltip, TooltipContent, @@ -13,7 +12,6 @@ import { TooltipTrigger, } from '~/components/ui/tooltip'; import { Settings } from 'lucide-react'; -import { Button } from '~/components/ui/Button'; import { DropdownMenuItem } from '~/components/ui/dropdown-menu'; type InterviewWithoutNetwork = Omit; From 3d23e006afb0886ebd116284a65f202e73b16d99 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 20:30:41 +0200 Subject: [PATCH 05/24] add workflow file for linting --- .github/workflows/lint.yml | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..e6c51ef7 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,41 @@ +name: Lint and TS Check + +on: + pull_request: + branches: + - '*' + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install dependencies + run: pnpm install + + - name: Run ESLint + run: pnpm run lint + + ts-lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install dependencies + run: pnpm install + + - name: Run TypeScript Lint + run: pnpm run ts-lint From a3cd4f7501f96de52a9e4fe87d819d3cb01318a7 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 20:33:34 +0200 Subject: [PATCH 06/24] update github action target --- .github/workflows/lint.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e6c51ef7..868b05b4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,6 +1,7 @@ name: Lint and TS Check on: + push: pull_request: branches: - '*' From c6452de440a743e0b37d2e55ed092b0b216bc31c Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 20:45:18 +0200 Subject: [PATCH 07/24] re-linting --- app/layout.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/layout.tsx b/app/layout.tsx index d824c540..558aee2a 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -3,7 +3,6 @@ import '~/styles/globals.scss'; import Providers from '../providers/Providers'; import RedirectWrapper from '~/components/RedirectWrapper'; import { trpc } from './_trpc/server'; -import type { Session } from 'lucia'; export const metadata = { title: 'Network Canvas Fresco', @@ -11,11 +10,12 @@ export const metadata = { }; async function RootLayout({ children }: { children: React.ReactNode }) { - const session = (await trpc.session.get.query(undefined, { + const session = await trpc.session.get.query(undefined, { context: { revalidate: 0, }, - })) as Session | null; + }); + const { expired, configured } = await trpc.appSettings.get.allappSettings.query(undefined, { context: { From aebfbef86c5640c02143c102b27d861f2a88634c Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 21:01:09 +0200 Subject: [PATCH 08/24] add standalone mode to next config --- next.config.mjs | 1 + prisma/schema.prisma | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index 51d1f040..a4e2d338 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -6,6 +6,7 @@ import('./env.mjs'); /** @type {import("next").NextConfig} */ const config = { + output: 'standalone', reactStrictMode: true, experimental: { serverActions: true, diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 807f97c7..77d7d462 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -2,7 +2,8 @@ // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { - provider = "prisma-client-js" + provider = "prisma-client-js" + binaryTargets = ["native", "linux-musl-arm64-openssl-3.0.x"] } datasource db { @@ -23,7 +24,7 @@ model Protocol { codebook Json assets Asset[] interviews Interview[] - active Boolean @default(false) + active Boolean @default(false) } model Asset { @@ -91,9 +92,9 @@ model Key { } model AppSettings { - configured Boolean @default(false) - initializedAt DateTime @default(now()) - configuredAt DateTime? + configured Boolean @default(false) + initializedAt DateTime @default(now()) + configuredAt DateTime? allowAnonymousRecruitment Boolean @default(false) @@id([configured, initializedAt]) From 262dc828541c88cb10523780813f5d78780139cc Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 21:10:00 +0200 Subject: [PATCH 09/24] update env schema --- env.mjs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/env.mjs b/env.mjs index 53e19b51..33adef3e 100644 --- a/env.mjs +++ b/env.mjs @@ -9,10 +9,6 @@ export const env = createEnv({ */ server: { DATABASE_URL: z.string().url(), - NODE_ENV: z - .enum(["development", "test", "production"]) - .default("development"), - VERCEL_URL: z.string().url().optional(), }, /** @@ -20,10 +16,10 @@ export const env = createEnv({ * isn't built with invalid env vars. To expose them to the client, prefix them with * `NEXT_PUBLIC_`. */ - client: { - NEXT_PUBLIC_URL: z.string().url(), - }, + client: {}, shared: { + NEXT_PUBLIC_URL: z.string().url().optional(), + VERCEL_URL: z.string().optional(), NODE_ENV: z .enum(["development", "test", "production"]) .default("development"), From f5fa55bd9bc5866e77db8382fe4f9224c8213bf8 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Tue, 10 Oct 2023 21:56:56 +0200 Subject: [PATCH 10/24] working docker build --- .dockerignore | 7 +++++++ Dockerfile | 32 ++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..72e9aa42 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 988ed3fd..6d2322bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,34 +6,36 @@ FROM base AS deps RUN apk add --no-cache libc6-compat WORKDIR /app -# Install dependencies based on the preferred package manager -COPY package.json pnpm-lock.yaml ./ -# Install pnpm -RUN npm install -g pnpm +# Prisma stuff +COPY prisma ./prisma -COPY . . +# Install dependencies +COPY package.json pnpm-lock.yaml* .env ./ +RUN pnpm i --frozen-lockfile -# Install dependencies using pnpm -RUN pnpm install # Rebuild the source code only when needed FROM base AS builder +WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . -RUN npm install -g pnpm - -RUN pnpm -v +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED 1 RUN pnpm run build +# If using npm comment out above and use below instead +# RUN npm run build + # Production image, copy all the files and run next FROM base AS runner WORKDIR /app ENV NODE_ENV production - # Uncomment the following line in case you want to disable telemetry during runtime. # ENV NEXT_TELEMETRY_DISABLED 1 @@ -41,7 +43,11 @@ RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --from=builder /app/public ./public -COPY --from=builder /app/package.json ./package.json + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + # Automatically leverage output traces to reduce image size # https://nextjs.org/docs/advanced-features/output-file-tracing COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ @@ -52,5 +58,7 @@ USER nextjs EXPOSE 3000 ENV PORT 3000 +# set hostname to localhost +ENV HOSTNAME "0.0.0.0" CMD ["node", "server.js"] \ No newline at end of file From 328036b1fc1bd95d541f51d157918a22d0e2a097 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 13:03:22 +0200 Subject: [PATCH 11/24] revert to vanilla uploadthing implementation --- .../_components/ProtocolUploader.tsx | 14 +--- utils/uploadthing/useUploadThing.ts | 80 ------------------- 2 files changed, 3 insertions(+), 91 deletions(-) delete mode 100644 utils/uploadthing/useUploadThing.ts diff --git a/app/(dashboard)/dashboard/_components/ProtocolUploader.tsx b/app/(dashboard)/dashboard/_components/ProtocolUploader.tsx index 437e2b83..1aef7252 100644 --- a/app/(dashboard)/dashboard/_components/ProtocolUploader.tsx +++ b/app/(dashboard)/dashboard/_components/ProtocolUploader.tsx @@ -2,7 +2,7 @@ import { useDropzone } from 'react-dropzone'; import { ChevronDown, ChevronUp } from 'lucide-react'; import type { FileWithPath } from 'react-dropzone'; -import { generateReactHelpers } from '~/utils/uploadthing/useUploadThing'; +import { generateReactHelpers } from '@uploadthing/react/hooks'; import { useState, useCallback } from 'react'; import { importProtocol } from '../_actions/importProtocol'; @@ -102,9 +102,8 @@ export default function ProtocolUploader({ }); }; - const { startUpload } = useUploadThing({ - endpoint: 'protocolUploader', - onClientUploadComplete: handleUploadComplete, + const { startUpload } = useUploadThing('protocolUploader', { + onClientUploadComplete: (res) => void handleUploadComplete(res), onUploadError: (error) => { setOpen(true); setDialogContent({ @@ -123,13 +122,6 @@ export default function ProtocolUploader({ error: '', }); }, - onUploadProgress: (file, progress) => { - // eslint-disable-next-line no-console - console.log( - '🚀 ~ file: ProtocolUploader.tsx:102 ~ ProtocolUploader ~ file>:progress', - `${file}>${progress}`, - ); - }, }); const onDrop = useCallback( diff --git a/utils/uploadthing/useUploadThing.ts b/utils/uploadthing/useUploadThing.ts deleted file mode 100644 index d995f940..00000000 --- a/utils/uploadthing/useUploadThing.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { useState } from 'react'; - -import { DANGEROUS__uploadFiles } from 'uploadthing/client'; -import type { FileRouter } from 'uploadthing/server'; - -import { useEvent } from './useEvent'; -import useFetch from './useFetch'; -import type { OurFileRouter } from '../../app/api/uploadthing/core'; - -type EndpointMetadata = { - slug: string; - config: OurFileRouter; -}[]; -const useEndpointMetadata = (endpoint: string) => { - const { data } = useFetch('/api/uploadthing'); - - // TODO: Log on errors in dev - - return data?.find((x) => x.slug === endpoint); -}; - -export const useUploadThing = ({ - endpoint, - onClientUploadComplete, - onUploadError, - onUploadBegin, - onUploadProgress, -}: { - endpoint: T; - onClientUploadComplete?: ( - res?: Awaited>, - ) => Promise; - onUploadError?: (e: Error) => void; - onUploadBegin?: () => void; - onUploadProgress?: (file: string, progress: number) => void; -}) => { - const [isUploading, setUploading] = useState(false); - - const permittedFileInfo = useEndpointMetadata(endpoint); - - const startUpload = useEvent(async (files: File[]) => { - setUploading(true); - try { - onUploadBegin?.(); - const res = await DANGEROUS__uploadFiles({ - endpoint, - onUploadProgress: ({ file, progress }) => { - onUploadProgress?.(file, progress); - }, - files, - }); - setUploading(false); - await onClientUploadComplete?.(res); - return res; - } catch (e) { - setUploading(false); - onUploadError?.(e as Error); - return; - } - }); - return { - startUpload, - isUploading, - permittedFileInfo, - } as const; -}; - -export const generateReactHelpers = () => { - type TRouterKey = keyof TRouter extends string ? keyof TRouter : string; - - return { - useUploadThing: useUploadThing, - uploadFiles: DANGEROUS__uploadFiles, - } as const; -}; - -export type FullFile = { - file: File; - contents: string; -}; From 1c6de8bb7e3648e724d448d378326b36c3b0bbde Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 13:04:32 +0200 Subject: [PATCH 12/24] remove unused uploadthing/shared package --- package.json | 1 - pnpm-lock.yaml | 3 --- 2 files changed, 4 deletions(-) diff --git a/package.json b/package.json index 82c8ca37..d2f7477b 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ "@trpc/server": "^10.38.3", "@types/validator": "^13.11.1", "@uploadthing/react": "^5.6.1", - "@uploadthing/shared": "^5.2.2", "ajv": "^8.12.0", "axios": "^1.5.0", "bcrypt": "^5.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 455ad752..a6b9043b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -101,9 +101,6 @@ dependencies: '@uploadthing/react': specifier: ^5.6.1 version: 5.6.1(next@13.5.2)(react@18.2.0)(uploadthing@5.6.1)(zod@3.22.2) - '@uploadthing/shared': - specifier: ^5.2.2 - version: 5.2.2(@uploadthing/mime-types@0.2.1)(zod@3.22.2) ajv: specifier: ^8.12.0 version: 8.12.0 From c30ffde93374fb4ca2e71f08defd31196073f291 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 15:46:04 +0200 Subject: [PATCH 13/24] remove postinstall script --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index d2f7477b..510f205b 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ "scripts": { "build": "next build", "dev": "next dev", - "postinstall": "prisma generate && prisma db push", "lint": "next lint", "ts-lint": "tsc --noEmit --incremental --watch", "start": "next start", From ada9856c466ca5fa3c24970ce80dc8420a197121 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 16:04:17 +0200 Subject: [PATCH 14/24] attempt to skip env validation for lint and ts-lint --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 510f205b..5358224a 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "scripts": { "build": "next build", "dev": "next dev", - "lint": "next lint", - "ts-lint": "tsc --noEmit --incremental --watch", + "lint": "SKIP_ENV_VALIDATION=true next lint", + "ts-lint": "SKIP_ENV_VALIDATION=true tsc --noEmit --incremental --watch", "start": "next start", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", From 058bfdce58b6fbb537ac6e60286ca279e82ab01b Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 16:06:22 +0200 Subject: [PATCH 15/24] remove --watch from ts-lint task --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5358224a..078003dd 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "build": "next build", "dev": "next dev", "lint": "SKIP_ENV_VALIDATION=true next lint", - "ts-lint": "SKIP_ENV_VALIDATION=true tsc --noEmit --incremental --watch", + "ts-lint": "SKIP_ENV_VALIDATION=true tsc --noEmit", + "ts-lint:watch": "SKIP_ENV_VALIDATION=true tsc --noEmit --incremental --watch", "start": "next start", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", From 09446ddd4efc31d0aa58cb70dbba580de29064c1 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 16:18:38 +0200 Subject: [PATCH 16/24] try freezing lockfile --- .github/workflows/lint.yml | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 868b05b4..11fe365d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,8 +18,21 @@ jobs: with: version: 8 + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - name: Install dependencies - run: pnpm install + run: pnpm install --frozen-lockfile - name: Run ESLint run: pnpm run lint @@ -35,8 +48,21 @@ jobs: with: version: 8 + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - name: Install dependencies - run: pnpm install + run: pnpm install --frozen-lockfile - name: Run TypeScript Lint run: pnpm run ts-lint From 74fbf39eebe59b8b8ec786336f17ae7394704285 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 16:26:25 +0200 Subject: [PATCH 17/24] switch to running build since it generates types and includes lint and ts-lint --- .github/workflows/lint.yml | 36 +++--------------------------------- package.json | 3 +-- 2 files changed, 4 insertions(+), 35 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 11fe365d..5687798c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,4 +1,4 @@ -name: Lint and TS Check +name: Build on: push: @@ -7,7 +7,7 @@ on: - '*' jobs: - lint: + build: runs-on: ubuntu-latest steps: @@ -35,34 +35,4 @@ jobs: run: pnpm install --frozen-lockfile - name: Run ESLint - run: pnpm run lint - - ts-lint: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - uses: pnpm/action-setup@v2 - with: - version: 8 - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - uses: actions/cache@v3 - name: Setup pnpm cache - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run TypeScript Lint - run: pnpm run ts-lint + run: pnpm run build diff --git a/package.json b/package.json index 078003dd..5358224a 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,7 @@ "build": "next build", "dev": "next dev", "lint": "SKIP_ENV_VALIDATION=true next lint", - "ts-lint": "SKIP_ENV_VALIDATION=true tsc --noEmit", - "ts-lint:watch": "SKIP_ENV_VALIDATION=true tsc --noEmit --incremental --watch", + "ts-lint": "SKIP_ENV_VALIDATION=true tsc --noEmit --incremental --watch", "start": "next start", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", From 2283741cb8a0cba93b94e8517510c13ae6a839a4 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 16:27:40 +0200 Subject: [PATCH 18/24] only run workflow on PR changes --- .github/workflows/lint.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5687798c..523513a1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,7 +1,6 @@ name: Build on: - push: pull_request: branches: - '*' From f0bbb501cfc6846ee1f8e42998745dab86870974 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 16:29:09 +0200 Subject: [PATCH 19/24] add SKIP_ENV_VALIDATION for workflow build --- .github/workflows/lint.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 523513a1..904c9518 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -33,5 +33,5 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Run ESLint - run: pnpm run build + - name: Run build + run: SKIP_ENV_VALIDATION pnpm next build From 5a3a8ccb6786a7fea6f8ea24f9865cc2bfc17f45 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 16:31:03 +0200 Subject: [PATCH 20/24] specify skip_env_validation differently in workflow --- .github/workflows/lint.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 904c9518..c468660d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,6 +5,9 @@ on: branches: - '*' +env: + SKIP_ENV_VALIDATION: true + jobs: build: runs-on: ubuntu-latest @@ -34,4 +37,4 @@ jobs: run: pnpm install --frozen-lockfile - name: Run build - run: SKIP_ENV_VALIDATION pnpm next build + run: pnpm next build From c57b0e2092cbbd53fc86befb3f3d91da9273daba Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 16:42:30 +0200 Subject: [PATCH 21/24] add next build cache and prisma client generation --- .github/workflows/lint.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c468660d..73981ae5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -36,5 +36,20 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Generate prisma client + run: pnpm prisma generate + + - uses: actions/cache@v3 + name: Setup next cache + with: + path: | + ${{ env.STORE_PATH }} + ${{ github.workspace }}/.next/cache + # Generate a new cache whenever packages or source files change. + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} + # If source files changed but packages didn't, rebuild from a prior cache. + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}- + - name: Run build run: pnpm next build From b2835a62f87fefadfe6bf732a61e39275aa7ca1e Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 17:40:57 +0200 Subject: [PATCH 22/24] fix Dockerfile --- Dockerfile | 18 ++++++++---------- package.json | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6d2322bf..5e88edde 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,18 @@ FROM node:18-alpine AS base +RUN corepack enable +ENV SKIP_ENV_VALIDATION=true # Install dependencies only when needed FROM base AS deps # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. RUN apk add --no-cache libc6-compat WORKDIR /app - - # Prisma stuff COPY prisma ./prisma - # Install dependencies -COPY package.json pnpm-lock.yaml* .env ./ -RUN pnpm i --frozen-lockfile +COPY package.json pnpm-lock.yaml* ./ +RUN pnpm install +RUN pnpm prisma generate # Rebuild the source code only when needed @@ -21,10 +21,8 @@ WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . -# Next.js collects completely anonymous telemetry data about general usage. -# Learn more here: https://nextjs.org/telemetry -# Uncomment the following line in case you want to disable telemetry during the build. -# ENV NEXT_TELEMETRY_DISABLED 1 + +ENV NEXT_TELEMETRY_DISABLED 1 RUN pnpm run build @@ -37,7 +35,7 @@ WORKDIR /app ENV NODE_ENV production # Uncomment the following line in case you want to disable telemetry during runtime. -# ENV NEXT_TELEMETRY_DISABLED 1 +ENV NEXT_TELEMETRY_DISABLED 1 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs diff --git a/package.json b/package.json index 5358224a..e4c0135f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "fresco", "version": "0.1.0", "private": true, - "packageManager": "^pnpm@8.6.3", + "packageManager": "pnpm@8.6.3", "engines": { "node": ">=18.16.0", "pnpm": ">=8.6.3" From 746f0d72653b9022f88c0b32d3707afee1928543 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 17:42:45 +0200 Subject: [PATCH 23/24] add sharp pacakge for Docker image optimization --- package.json | 1 + pnpm-lock.yaml | 187 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 176 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index e4c0135f..1e759d0e 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "react-dropzone": "^14.2.3", "react-hook-form": "^7.46.1", "sass": "^1.67.0", + "sharp": "^0.32.6", "superjson": "1.13.1", "tailwind-merge": "^1.14.0", "tailwindcss-animate": "^1.0.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a6b9043b..4003400f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -161,6 +161,9 @@ dependencies: sass: specifier: ^1.67.0 version: 1.67.0 + sharp: + specifier: ^0.32.6 + version: 0.32.6 superjson: specifier: 1.13.1 version: 1.13.1 @@ -6333,6 +6336,10 @@ packages: dequal: 2.0.3 dev: true + /b4a@1.6.4: + resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + dev: false + /babel-core@7.0.0-bridge.0(@babel/core@7.22.20): resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} peerDependencies: @@ -6489,7 +6496,6 @@ packages: /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true /bcrypt@5.1.1: resolution: {integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==} @@ -6528,7 +6534,6 @@ packages: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 - dev: true /blobs@2.3.0-beta.2: resolution: {integrity: sha512-kzLT5TOg/hsETxeyHae1sNpRWXNHnB1VN467FASoZfLRm4LdoXyp6HTTjes0cPE1sOVoOHEJFT9qyFGOpQFvPw==} @@ -6694,7 +6699,6 @@ packages: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: true /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} @@ -6846,7 +6850,6 @@ packages: /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: true /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} @@ -6986,11 +6989,26 @@ packages: /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + /color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: false + /color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true dev: false + /color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: false + /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} dev: true @@ -7351,6 +7369,13 @@ packages: dependencies: ms: 2.1.2 + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: false + /dedent@0.7.0: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} dev: true @@ -7387,6 +7412,11 @@ packages: which-typed-array: 1.1.11 dev: true + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: false + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -7760,7 +7790,6 @@ packages: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 - dev: true /endent@2.1.0: resolution: {integrity: sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==} @@ -8390,6 +8419,11 @@ packages: engines: {node: '>= 0.8.0'} dev: true + /expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + dev: false + /expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -8462,6 +8496,10 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: false + /fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + dev: false + /fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} @@ -8759,7 +8797,6 @@ packages: /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - dev: true /fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} @@ -8901,6 +8938,10 @@ packages: - supports-color dev: true + /github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + dev: false + /github-slugger@1.5.0: resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} dev: true @@ -9323,7 +9364,6 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} @@ -9382,6 +9422,10 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: false + /inline-style-parser@0.1.1: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} dev: false @@ -9445,6 +9489,10 @@ packages: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: true + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: false + /is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} @@ -10832,6 +10880,11 @@ packages: engines: {node: '>=12'} dev: false + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: false + /min-document@2.19.0: resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} dependencies: @@ -10877,7 +10930,6 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true /minipass@3.3.6: resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} @@ -10903,7 +10955,6 @@ packages: /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - dev: true /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} @@ -10949,6 +11000,10 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + /napi-build-utils@1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + dev: false + /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -11008,6 +11063,13 @@ packages: tslib: 2.6.2 dev: true + /node-abi@3.49.0: + resolution: {integrity: sha512-ji8IK8VT2zAQv9BeOqwnpuvJnCivxPCe2HNiPe8P1z1SDhqEFpm7GqctqTWkujb8mLfZ1PWDrjMeiq6l9TN7fA==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: false + /node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} dev: true @@ -11016,6 +11078,10 @@ packages: resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} dev: false + /node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + dev: false + /node-dir@0.1.17: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} @@ -11723,6 +11789,25 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /prebuild-install@7.1.1: + resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + detect-libc: 2.0.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.49.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + dev: false + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -11911,7 +11996,6 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 - dev: true /pumpify@1.5.1: resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} @@ -11975,6 +12059,10 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + /queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + dev: false + /queue@6.0.2: resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} dependencies: @@ -12013,6 +12101,16 @@ packages: unpipe: 1.0.0 dev: true + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + dev: false + /react-colorful@5.6.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} peerDependencies: @@ -12814,6 +12912,21 @@ packages: kind-of: 6.0.3 dev: true + /sharp@0.32.6: + resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} + engines: {node: '>=14.15.0'} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.2 + node-addon-api: 6.1.0 + prebuild-install: 7.1.1 + semver: 7.5.4 + simple-get: 4.0.1 + tar-fs: 3.0.4 + tunnel-agent: 0.6.0 + dev: false + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -12840,6 +12953,24 @@ packages: engines: {node: '>=14'} dev: true + /simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + dev: false + + /simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + dev: false + + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + dependencies: + is-arrayish: 0.3.2 + dev: false + /simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} @@ -13019,6 +13150,13 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + /streamx@2.15.1: + resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} + dependencies: + fast-fifo: 1.3.2 + queue-tick: 1.0.1 + dev: false + /string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -13132,6 +13270,11 @@ packages: min-indent: 1.0.1 dev: true + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: false + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -13303,7 +13446,14 @@ packages: mkdirp-classic: 0.5.3 pump: 3.0.0 tar-stream: 2.2.0 - dev: true + + /tar-fs@3.0.4: + resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} + dependencies: + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 3.1.6 + dev: false /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -13314,7 +13464,14 @@ packages: fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.2 - dev: true + + /tar-stream@3.1.6: + resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} + dependencies: + b4a: 1.6.4 + fast-fifo: 1.3.2 + streamx: 2.15.1 + dev: false /tar@6.2.0: resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} @@ -13591,6 +13748,12 @@ packages: resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} dev: true + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: false + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} From 65d800ac1bf9a48f2334aa3a1fa74691db816f33 Mon Sep 17 00:00:00 2001 From: Joshua Melville Date: Wed, 11 Oct 2023 17:54:38 +0200 Subject: [PATCH 24/24] add untested docker build workflow --- .github/workflows/push.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/push.yml diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 00000000..54ac48fe --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,35 @@ +name: Build docker container +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + +env: + SKIP_ENV_VALIDATION: true + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set env + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + + - name: Build the production image + run: docker build -t fresco . + + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push the production image to the container registry + if: github.ref == 'refs/heads/master' + run: | + docker tag app ghcr.io/${{ github.repository }}:${{ env.RELEASE_VERSION }} + docker push ghcr.io/${{ github.repository }}:${{ env.RELEASE_VERSION }}