diff --git a/.gitignore b/.gitignore index 74afc5d..0653358 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,8 @@ web_modules/ .env .env.* !.env.example +curl.txt + # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/client/src/lib/api.ts b/client/src/lib/api.ts index b8f29f7..6a43724 100644 --- a/client/src/lib/api.ts +++ b/client/src/lib/api.ts @@ -1,3 +1,5 @@ +import { usePipelineStore } from "../store/usePipelineStore"; + export const BASE = import.meta.env.VITE_API_BASE ?? "http://localhost:3000/api"; @@ -139,35 +141,82 @@ export const api = { return { results }; }, - // --- Mock deploy APIs for Dashboard --- - async startDeploy({ repo, env }: { repo: string; env: string }) { - const jobId = `job_${Math.random().toString(36).slice(2)}`; - // Stash minimal job info in memory for the stream to reference - JOBS.set(jobId, { repo, env, startedAt: Date.now() }); - return { jobId } as const; - }, + // --- Deploy APIs for Dashboard --- +async startDeploy({ + repoFullName: fromCallerRepo, + branch, + env, + yaml: fromCallerYaml, + provider, + path, +}: { + repoFullName?: string; + branch?: string; + env?: string; + yaml?: string; + provider?: string; + path?: string; +}) { + const pipelineStore = usePipelineStore.getState(); + const repoFullName = fromCallerRepo || pipelineStore?.repoFullName || pipelineStore?.result?.repo; + const selectedBranch = branch || pipelineStore?.selectedBranch || "main"; + const yaml = pipelineStore?.result?.generated_yaml; + const environment = env || pipelineStore?.environment || "dev"; + + const providerFinal = provider || pipelineStore?.provider || "aws"; + const pathFinal = path || `.github/workflows/${environment}-deploy.yml`; + + console.group("[Deploy Debug]"); + console.log("repoFullName:", repoFullName); + console.log("selectedBranch:", selectedBranch); + console.log("environment:", environment); + console.log("provider:", providerFinal); + console.log("path:", pathFinal); + console.log("YAML length:", yaml ? yaml.length : 0); + console.groupEnd(); + + const payload = { + repoFullName, + branch: selectedBranch, + env: environment, + yaml, + provider: providerFinal, + path: pathFinal, + }; + + console.log("[Deploy] Final payload:", payload); + + const res = await fetch(`${SERVER_BASE}/mcp/v1/pipeline_commit`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + credentials: "include", + body: JSON.stringify(payload), + }); + + const data = await res.json().catch(() => ({})); + + console.group("[Deploy Response]"); + console.log("Status:", res.status); + console.log("Data:", data); + console.groupEnd(); + + if (!res.ok) throw new Error(`Pipeline commit failed: ${res.statusText}`); + return data; +}, - streamJob( - jobId: string, - onEvent: (e: { ts: string; level: "info" | "warn" | "error"; msg: string }) => void - ) { - const meta = JOBS.get(jobId) || { repo: "?", env: "dev" }; + streamJob(_jobId: string, onEvent: (e: { ts: string; level: "info"; msg: string }) => void) { const steps = [ - `Authenticating to AWS (${meta.env})`, - `Assuming role`, - `Validating permissions`, - `Building artifacts`, - `Deploying ${meta.repo}`, - `Verifying rollout`, - `Done` + "Connecting to GitHub...", + "Committing workflow file...", + "Verifying commit...", + "Done ✅" ]; let i = 0; const timer = setInterval(() => { if (i >= steps.length) return; - const level = i === steps.length - 1 ? "info" : "info"; - onEvent({ ts: new Date().toISOString(), level, msg: steps[i++] }); + onEvent({ ts: new Date().toISOString(), level: "info", msg: steps[i++] }); if (i >= steps.length) clearInterval(timer); - }, 800); + }, 600); return () => clearInterval(timer); }, }; diff --git a/client/src/pages/ConfigurePage.tsx b/client/src/pages/ConfigurePage.tsx index 4003081..dee3edc 100644 --- a/client/src/pages/ConfigurePage.tsx +++ b/client/src/pages/ConfigurePage.tsx @@ -122,7 +122,7 @@ export default function ConfigurePage() {
+
{pipeline.result?.yaml ?? pipeline.result?.generated_yaml ?? "Click Generate Pipeline to preview YAML…"}
+{result?.generated_yaml ?? "No pipeline generated yet."}@@ -42,15 +47,40 @@ export default function DashboardPage() {{running && }- Logs + Commit Logs{events.length === 0 ? "No logs yet." : events.map((e, i) => ( diff --git a/client/src/pages/DeployPage.tsx b/client/src/pages/DeployPage.tsx index b8d404e..8eb1b1f 100644 --- a/client/src/pages/DeployPage.tsx +++ b/client/src/pages/DeployPage.tsx @@ -10,15 +10,29 @@ export default function DeployPage() { // loadRoles(); }, []); + function startCommit() { + // Placeholder function to start commit process + console.log("Commit to GitHub started"); + } + return (+); } diff --git a/client/src/store/useDeployStore.ts b/client/src/store/useDeployStore.ts index e53560c..a5d5449 100644 --- a/client/src/store/useDeployStore.ts +++ b/client/src/store/useDeployStore.ts @@ -19,13 +19,29 @@ type DeployActions = { export const useDeployStore = createCommit Workflow to GitHub
{!repo || !branch ? (Pick a repo/branch on Connect first.
) : ( -Deploying {repo} @ {branch}
+ <> +Committing workflow to GitHub for {repo} @ {branch}
+ + > )} - {/* role picker + open PR button go here, wired to your deploy store */} + {/* role picker + commit to GitHub button go here, wired to your deploy store */}()((set) => ({ running: false, events: [], - async startDeploy({ repo, env }) { + async startDeploy(payload: { + repoFullName: string; + branch?: string; + env: string; + yaml?: string; + provider?: string; + path?: string; + }) { + const { repoFullName, branch = "main", env, yaml, provider = "aws", path = `.github/workflows/${env}-deploy.yml` } = payload || {}; set({ running: true, events: [] }); - const { jobId } = await api.startDeploy({ repo, env }); - const stop = api.streamJob(jobId, (e) => - set((s) => ({ events: [...s.events, e] })) - ); - set({ jobId, stopStream: stop }); + try { + console.group("[useDeployStore.startDeploy] Prepared payload"); + console.log({ repoFullName, branch, env, provider, path, yamlLength: yaml ? yaml.length : 0 }); + console.groupEnd(); + const { jobId } = await api.startDeploy({ repoFullName, branch, env, yaml, provider, path }); + const stop = api.streamJob(jobId, (e) => + set((s) => ({ events: [...s.events, e] })) + ); + set({ jobId, stopStream: stop }); + } catch (err) { + console.error("[useDeployStore.startDeploy] Error:", err); + set({ running: false }); + } }, stop() { set((s) => { diff --git a/client/src/store/usePipelineStore.ts b/client/src/store/usePipelineStore.ts index 19ae342..1bd1b87 100644 --- a/client/src/store/usePipelineStore.ts +++ b/client/src/store/usePipelineStore.ts @@ -18,6 +18,7 @@ type PipelineState = { // outputs from MCP result?: McpPipeline; + repoFullName?: string; // local UI state roles: { name: string; arn: string }[]; @@ -117,8 +118,16 @@ export const usePipelineStore = create ()((set, res?.generated_yaml || ""; + const repoFullName = + res?.data?.data?.repo || + res?.data?.repo || + ""; + + console.log("[usePipelineStore] Captured repoFullName:", repoFullName); + set({ - result: { ...res, yaml: generated_yaml }, + result: { ...res, yaml: generated_yaml, generated_yaml }, + repoFullName, status: "success", editing: false, editedYaml: undefined,