9645aebce1
- Add workspace-level pnpm install in Dockerfile so pnpm-workspace.yaml supply-chain settings (onlyBuiltDependencies, allowBuilds) apply uniformly - Pin pnpm@11.5.2 via corepack with sha1 hash to prevent future policy drift - Downgrade postcss to ^8.5.22 (8.5.23 was <24h old, violated minimumReleaseAge) - Regenerate frontend/pnpm-lock.yaml and add root pnpm-lock.yaml for full workspace - Add binaryTargets to Prisma schema for linux-musl (Alpine) + debian compatibility - Run pnpm approve-builds to set allowBuilds for esbuild, ssh2, prisma, @prisma/* - Fix docker-compose.yml: postgres:18-alpine volume at /var/lib/postgresql (not /data) - Add .env.docker.example; ignore .env.docker in .gitignore Integration tests (Docker Compose against real Gitea 1.26.2): ✅ Docker image builds cleanly (pnpm frozen-lockfile, no policy violations) ✅ postgres:18-alpine starts healthy ✅ Prisma migrations run on startup ✅ Founder registration and session auth ✅ Gitea connection validated (PAT scope check) ✅ Webhook registered on test repo (Hook ID 11) ✅ PR opened → HMAC verified → preview created → DEPLOY job queued ✅ Gitea PR comment posted (write:issue scope confirmed working) ✅ Deploy fails correctly at AWS step: "Region is missing" (no creds in test env) ✅ PR closed → STOP job created and completed (status DONE) ✅ HMAC rejection: wrong signature → 401 ✅ /pp stop via issue_comment webhook → accepted Blocked (expected): EC2 provisioning requires AWS credentials not present in CI/test env. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
162 lines
4.5 KiB
Plaintext
162 lines
4.5 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
binaryTargets = ["native", "debian-openssl-3.0.x", "linux-musl-openssl-3.0.x"]
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum PreviewStatus {
|
|
PROVISIONING
|
|
BUILDING
|
|
RUNNING
|
|
FAILED
|
|
STOPPED
|
|
IGNORED
|
|
}
|
|
|
|
enum JobType {
|
|
DEPLOY
|
|
STOP
|
|
INACTIVITY_STOP
|
|
}
|
|
|
|
enum JobStatus {
|
|
PENDING
|
|
RUNNING
|
|
DONE
|
|
FAILED
|
|
}
|
|
|
|
model User {
|
|
id Int @id @default(autoincrement())
|
|
username String @unique @db.VarChar(128)
|
|
passwordHash String @db.VarChar(256)
|
|
isAdmin Boolean @default(false)
|
|
isFounder Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
giteaUsername String? @db.VarChar(128)
|
|
giteaPAT String? @db.Text
|
|
giteaInstanceUrl String? @db.VarChar(512)
|
|
|
|
awsAccessKeyId String? @db.VarChar(256)
|
|
awsSecretAccessKey String? @db.Text
|
|
awsRegion String? @db.VarChar(64)
|
|
|
|
sessions Session[]
|
|
repoConfigs RepoConfig[]
|
|
webhookToken WebhookToken?
|
|
noConfigComments NoConfigComment[]
|
|
}
|
|
|
|
model Session {
|
|
id Int @id @default(autoincrement())
|
|
hash String @db.VarChar(512)
|
|
userId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model RepoConfig {
|
|
id Int @id @default(autoincrement())
|
|
userId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
repoOwner String @db.VarChar(128)
|
|
repoName String @db.VarChar(128)
|
|
isEnabled Boolean @default(false)
|
|
|
|
giteaWebhookId String? @db.VarChar(128)
|
|
|
|
denyList String[]
|
|
instanceType String @default("t2.medium") @db.VarChar(64)
|
|
inactivityHours Float @default(12)
|
|
port Int @default(3000)
|
|
envVars Json @default("{}")
|
|
useDockerCompose Boolean @default(false)
|
|
composeFilePath String? @db.VarChar(512)
|
|
aptPackages String[]
|
|
setupCommands String[]
|
|
buildCommands String[]
|
|
postBuildCommands String[]
|
|
runCommand String? @db.Text
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
previews Preview[]
|
|
|
|
@@unique([repoOwner, repoName])
|
|
}
|
|
|
|
model Preview {
|
|
id Int @id @default(autoincrement())
|
|
repoConfigId Int
|
|
repoConfig RepoConfig @relation(fields: [repoConfigId], references: [id], onDelete: Cascade)
|
|
prNumber Int
|
|
prTitle String @db.VarChar(512)
|
|
commitSha String @db.VarChar(64)
|
|
instanceId String? @db.VarChar(64)
|
|
instanceIp String? @db.VarChar(64)
|
|
port Int @default(3000)
|
|
status PreviewStatus @default(PROVISIONING)
|
|
logs String @default("") @db.Text
|
|
pid Int?
|
|
sshPrivateKey String? @db.Text
|
|
sshKeyName String? @db.VarChar(128)
|
|
giteaCommentId Int?
|
|
lastActivityAt DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
stoppedAt DateTime?
|
|
|
|
jobs Job[]
|
|
}
|
|
|
|
model Job {
|
|
id Int @id @default(autoincrement())
|
|
previewId Int?
|
|
preview Preview? @relation(fields: [previewId], references: [id], onDelete: Cascade)
|
|
type JobType
|
|
status JobStatus @default(PENDING)
|
|
payload Json @default("{}")
|
|
error String? @db.Text
|
|
createdAt DateTime @default(now())
|
|
startedAt DateTime?
|
|
finishedAt DateTime?
|
|
}
|
|
|
|
model WebhookToken {
|
|
id Int @id @default(autoincrement())
|
|
userId Int @unique
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
token String @db.VarChar(256)
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model NoConfigComment {
|
|
id Int @id @default(autoincrement())
|
|
userId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
repoOwner String @db.VarChar(128)
|
|
repoName String @db.VarChar(128)
|
|
prNumber Int
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([userId, repoOwner, repoName, prNumber])
|
|
}
|
|
|
|
model AdminSettings {
|
|
id Int @id @default(1)
|
|
defaultInstanceType String @default("t2.medium") @db.VarChar(64)
|
|
maxConcurrentInstancesPerUser Int @default(5)
|
|
logSizeLimitBytes Int @default(1048576)
|
|
previewRetentionDays Int @default(30)
|
|
webhookRateLimitPerMinute Int @default(10)
|
|
contactEmail String @default("") @db.VarChar(256)
|
|
}
|