feat(applications): add watch paths for selective deployments

- Implement watch paths feature for GitHub and GitLab applications and compose services
- Add ability to specify paths that trigger deployments when changed
- Update database schemas to support watch paths
- Integrate micromatch for flexible path matching
- Enhance deployment triggers with granular file change detection
This commit is contained in:
Mauricio Siu
2025-03-08 23:32:08 -06:00
parent 1ad25ca6d1
commit c1aeb828d8
24 changed files with 11293 additions and 33 deletions

View File

@@ -28,6 +28,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"micromatch":"4.0.8",
"@ai-sdk/anthropic": "^1.0.6",
"@ai-sdk/azure": "^1.0.15",
"@ai-sdk/cohere": "^1.0.6",
@@ -79,6 +80,7 @@
"zod": "^3.23.4"
},
"devDependencies": {
"@types/micromatch": "4.0.9",
"@types/adm-zip": "^0.5.5",
"@types/bcrypt": "5.0.2",
"@types/dockerode": "3.3.23",

View File

@@ -116,6 +116,7 @@ export const applications = pgTable("application", {
description: text("description"),
env: text("env"),
previewEnv: text("previewEnv"),
watchPaths: text("watchPaths").array(),
previewBuildArgs: text("previewBuildArgs"),
previewWildcard: text("previewWildcard"),
previewPort: integer("previewPort").default(3000),
@@ -406,6 +407,7 @@ const createSchema = createInsertSchema(applications, {
previewHttps: z.boolean().optional(),
previewPath: z.string().optional(),
previewCertificateType: z.enum(["letsencrypt", "none", "custom"]).optional(),
watchPaths: z.array(z.string()).optional(),
});
export const apiCreateApplication = createSchema.pick({
@@ -449,6 +451,7 @@ export const apiSaveGithubProvider = createSchema
owner: true,
buildPath: true,
githubId: true,
watchPaths: true,
})
.required();
@@ -462,6 +465,7 @@ export const apiSaveGitlabProvider = createSchema
gitlabId: true,
gitlabProjectId: true,
gitlabPathNamespace: true,
watchPaths: true,
})
.required();
@@ -473,6 +477,7 @@ export const apiSaveBitbucketProvider = createSchema
bitbucketRepository: true,
bitbucketId: true,
applicationId: true,
watchPaths: true,
})
.required();
@@ -492,6 +497,7 @@ export const apiSaveGitProvider = createSchema
applicationId: true,
customGitBuildPath: true,
customGitUrl: true,
watchPaths: true,
})
.required()
.merge(

View File

@@ -77,7 +77,7 @@ export const compose = pgTable("compose", {
createdAt: text("createdAt")
.notNull()
.$defaultFn(() => new Date().toISOString()),
watchPaths: text("watchPaths").array(),
githubId: text("githubId").references(() => github.githubId, {
onDelete: "set null",
}),
@@ -132,6 +132,7 @@ const createSchema = createInsertSchema(compose, {
command: z.string().optional(),
composePath: z.string().min(1),
composeType: z.enum(["docker-compose", "stack"]).optional(),
watchPaths: z.array(z.string()).optional(),
});
export const apiCreateCompose = createSchema.pick({

View File

@@ -40,7 +40,7 @@ export * from "./setup/setup";
export * from "./setup/traefik-setup";
export * from "./setup/server-validate";
export * from "./setup/server-audit";
export * from "./utils/watch-paths/should-deploy";
export * from "./utils/backups/index";
export * from "./utils/backups/mariadb";
export * from "./utils/backups/mongo";

View File

@@ -0,0 +1,9 @@
import micromatch from "micromatch";
export const shouldDeploy = (
watchPaths: string[] | null,
modifiedFiles: string[],
): boolean => {
if (!watchPaths || watchPaths?.length === 0) return true;
return micromatch.some(modifiedFiles, watchPaths);
};