diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4877921..a6b3382 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,18 @@ name: CI on: push: branches: - - main - - master + - prod + paths-ignore: + - 'README.md' + - '*.md' + - 'docs/**' pull_request: + branches: + - prod + paths-ignore: + - 'README.md' + - '*.md' + - 'docs/**' permissions: contents: read @@ -58,3 +67,16 @@ jobs: - name: Run build run: npm run build + + - name: Trigger Inngest CI Workflow + if: ${{ secrets.INNGEST_EVENT_KEY != '' }} + run: | + curl --fail -X POST https://api.inngest.com/e/${{ secrets.INNGEST_EVENT_KEY }} \ + -H "Content-Type: application/json" \ + -d '{ + "name": "ci/workflow.triggered", + "data": { + "ref": "${{ github.ref }}", + "sha": "${{ github.sha }}" + } + }' diff --git a/app/api/inngest/route.ts b/app/api/inngest/route.ts index 9cf9a9d..d4b07fd 100644 --- a/app/api/inngest/route.ts +++ b/app/api/inngest/route.ts @@ -8,10 +8,33 @@ import { runVibetest } from "@/lib/test-functions/vibetest-run"; import { runSecurityAgent } from "@/lib/security-agent/functions"; import { indexDeploymentLogs, cronReindexLogs } from "@/lib/vector-indexer"; // ← add this +const handleCiWorkflow = inngest.createFunction( + { id: "handle-ci-workflow" }, + { event: "ci/workflow.triggered" }, + async ({ event, step }) => { + const { ref, sha } = event.data; + + await step.run("execute-safely", async () => { + console.log(`Processing build for Ref: ${ref}, SHA: ${sha}`); + + // Send the event to start the actual test suites in the app + await inngest.send({ + name: "test/suite.run", + data: { + runId: `ci-${sha.slice(0, 7)}`, + sandboxId: "production-ci-environment", + }, + }); + + return { status: "test_suite_dispatched" }; + }); + } +); + // Allow Inngest handler up to 5 minutes (max for Vercel hobby plan) export const maxDuration = 300; export const { GET, POST, PUT } = serve({ client: inngest, - functions: [runTestSuite, runSecurityScan, runApiTests, runPerformanceTests, runVibetest, runSecurityAgent, indexDeploymentLogs, cronReindexLogs], + functions: [runTestSuite, runSecurityScan, runApiTests, runPerformanceTests, runVibetest, runSecurityAgent, indexDeploymentLogs, cronReindexLogs, handleCiWorkflow], }); \ No newline at end of file diff --git a/app/api/tests/run/route.ts b/app/api/tests/run/route.ts index 2d2f712..1e76cff 100644 --- a/app/api/tests/run/route.ts +++ b/app/api/tests/run/route.ts @@ -12,7 +12,7 @@ import { getDb, ensureTables } from "@/lib/db"; import { randomBytes } from "node:crypto"; import { auth } from "@/lib/auth"; -const EVENT_MAP: Record = { +const EVENT_MAP: Record = { suite: "test/suite.run", security: "test/security.run", api: "test/api.run", diff --git a/lib/inngest.ts b/lib/inngest.ts index 926a5fa..4e854f2 100644 --- a/lib/inngest.ts +++ b/lib/inngest.ts @@ -1,6 +1,23 @@ -import { Inngest } from "inngest"; +import { Inngest, EventSchemas } from "inngest"; -export const inngest = new Inngest({ - id: "secdev", - eventKey: process.env.INNGEST_EVENT_KEY, +type Events = { + "ci/workflow.triggered": { + data: { + ref: string; + sha: string; + }; + }; + "log/index.requested": { data: { sandboxId: string; userId: string; ttlDays: number } }; + "log/index.cron": { data: Record }; + "security-agent/scan.run": { data: { runId: string; sandboxId: string } }; + "test/api.run": { data: { runId: string; sandboxId: string } }; + "test/performance.run": { data: { runId: string; sandboxId: string } }; + "test/security.run": { data: { runId: string; sandboxId: string } }; + "test/suite.run": { data: { runId: string; sandboxId: string } }; + "test/vibetest.run": { data: { runId: string; sandboxId: string } }; +}; + +export const inngest = new Inngest({ + id: "secdev-app", + schemas: new EventSchemas().fromRecord() });