From 3f963cf12f66c0dda1b01aa1736b7e5af8a9d89f Mon Sep 17 00:00:00 2001 From: Tomas Francisco <4301103+tomasfrancisco@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:29:17 +0200 Subject: [PATCH] push to github on resources update --- .../src/components/navigation/navigation.tsx | 92 +++++++++++-------- packages/api/src/operations/release.ts | 47 ++++++++++ packages/api/src/router/resources.ts | 13 ++- .../src/schema/resources/resources.ts | 5 +- .../services/src/github/utils/push-file.ts | 2 +- 5 files changed, 115 insertions(+), 44 deletions(-) create mode 100644 packages/api/src/operations/release.ts diff --git a/apps/dashboard/src/components/navigation/navigation.tsx b/apps/dashboard/src/components/navigation/navigation.tsx index c743c17..00c2553 100644 --- a/apps/dashboard/src/components/navigation/navigation.tsx +++ b/apps/dashboard/src/components/navigation/navigation.tsx @@ -1,4 +1,5 @@ import { + Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, @@ -24,48 +25,63 @@ export function Navigation({ className, projects }: NavigationProps) { return ( ); } diff --git a/packages/api/src/operations/release.ts b/packages/api/src/operations/release.ts new file mode 100644 index 0000000..73c6139 --- /dev/null +++ b/packages/api/src/operations/release.ts @@ -0,0 +1,47 @@ +import { getInstallationOctokit, pushFile } from '@ds-project/services/github'; +import { selectGithubIntegration } from '../queries/integrations'; +import type { DSContext } from '../types/context'; +import type { DesignTokensModel } from '@ds-project/database/schema'; + +export async function release({ + ctx, + designTokens, +}: { + ctx: DSContext; + designTokens: DesignTokensModel | null; +}) { + const githubIntegration = await selectGithubIntegration({ ctx }); + + if (!githubIntegration) { + console.log('No GitHub integration found. Skipping release.'); + return; + } + + const octokit = await getInstallationOctokit( + githubIntegration.data.installationId + ); + + const repositories = await octokit.request('GET /installation/repositories'); + const repository = repositories.data.repositories.find( + (_repository) => _repository.id === githubIntegration.data.repositoryId + ); + + if (!repository) { + console.log('No repository found. Skipping release.'); + return; + } + + const content = btoa(JSON.stringify(designTokens, null, 2)); + + await pushFile({ + file: { + content, + encoding: 'base64', + name: 'tokens.json', + path: 'packages/generator/tokens', + }, + installationId: githubIntegration.data.installationId, + owner: repository.owner.login, + repo: repository.name, + }); +} diff --git a/packages/api/src/router/resources.ts b/packages/api/src/router/resources.ts index 461745b..144207b 100644 --- a/packages/api/src/router/resources.ts +++ b/packages/api/src/router/resources.ts @@ -8,6 +8,7 @@ import { PreprocessedTokensSchema, Resources, } from '@ds-project/database/schema'; +import { release } from '../operations/release'; export const resourcesRouter = createTRPCRouter({ byId: protectedProcedure @@ -55,7 +56,7 @@ export const resourcesRouter = createTRPCRouter({ }) ) .mutation(async ({ ctx, input }) => { - const result = await ctx.database + const [resource] = await ctx.database .insert(Resources) .values({ name: input.name, @@ -69,10 +70,16 @@ export const resourcesRouter = createTRPCRouter({ set: { designTokens: PreprocessedTokensSchema.parse(input.designTokens), }, + }) + .returning({ + insertedDesignTokens: Resources.designTokens, }); - // TODO: Run update to Integration here ---> GitHub - return result; + if (!resource) return resource; + + await release({ ctx, designTokens: resource.insertedDesignTokens }); + + return resource; }), create: protectedProcedure diff --git a/packages/database/src/schema/resources/resources.ts b/packages/database/src/schema/resources/resources.ts index 3cbd4a2..cbf9ba1 100644 --- a/packages/database/src/schema/resources/resources.ts +++ b/packages/database/src/schema/resources/resources.ts @@ -41,6 +41,8 @@ const DesignTokensSchema: z.ZodType = z.lazy(() => export const PreprocessedTokensSchema: z.ZodType = z.lazy(() => z.union([DesignTokenSchema, PreprocessedTokensSchema])); +export type DesignTokensModel = z.infer; + /** * Represents the resources linked to a design system. */ @@ -57,8 +59,7 @@ export const Resources = pgTable('resources', { .references(() => Projects.id, { onDelete: 'cascade' }) .notNull(), name: text('name').notNull().unique(), - designTokens: - json('design_tokens').$type>(), + designTokens: json('design_tokens').$type(), }); export const InsertResourcesSchema = createInsertSchema(Resources, { diff --git a/packages/services/src/github/utils/push-file.ts b/packages/services/src/github/utils/push-file.ts index 5839d0e..dd28b11 100644 --- a/packages/services/src/github/utils/push-file.ts +++ b/packages/services/src/github/utils/push-file.ts @@ -105,7 +105,7 @@ export async function pushFile({ base_tree: baseCommitSha, tree: [ { - path: `${file.path ?? ''}${file.name}`, + path: `${file.path ?? ''}/${file.name}`, mode: '100644', type: 'blob', sha: blobSha,