Skip to content

Commit 7e354d3

Browse files
committed
Add provider support, dynamic pipeline generation, and full AWS/Jenkins branching
- Added provider field to pipeline store with setProvider action - Updated regenerate() to send full payload including node_version, commands, aws_role_arn, and stages - Added provider selector UI in ConfigurePage with conditional AWS fields - Updated api.createPipeline to forward full payload to backend (removed restricted body) - Enhanced pipeline_generator to support provider-based branching (AWS OIDC vs Jenkins workflow) - Fixed stages return value and improved dynamic YAML generation
1 parent 01ab71b commit 7e354d3

File tree

6 files changed

+428
-82
lines changed

6 files changed

+428
-82
lines changed

client/src/lib/api.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,7 @@ export const api = {
5959

6060
async createPipeline(payload: any) {
6161
const { repo, branch, template = "node_app", options } = payload || {};
62-
const data = await mcp("pipeline_generator", {
63-
repo,
64-
branch,
65-
provider: "aws",
66-
template,
67-
options: options || {},
68-
});
62+
const data = await mcp("pipeline_generator", payload);
6963
return data;
7064
},
7165

client/src/pages/ConfigurePage.tsx

Lines changed: 69 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export default function ConfigurePage() {
2727
useEffect(() => {
2828
if (!repo || !branch) return;
2929
pipeline.loadAwsRoles?.().catch(console.error);
30-
}, [repo, branch, pipeline]);
30+
// eslint-disable-next-line react-hooks/exhaustive-deps
31+
}, []);
3132

3233
async function regenerateNow() {
3334
if (!repo || !branch) return;
@@ -74,6 +75,18 @@ export default function ConfigurePage() {
7475
</div>
7576
</div>
7677

78+
{/* Provider */}
79+
<label className="space-y-2">
80+
<div className="font-medium">Provider</div>
81+
<select
82+
value={pipeline.provider}
83+
onChange={(e) => pipeline.setProvider?.(e.target.value as "aws" | "jenkins")}
84+
className="block rounded-md border px-3 py-2"
85+
>
86+
<option value="aws">AWS (OIDC)</option>
87+
<option value="jenkins">Jenkins</option>
88+
</select>
89+
</label>
7790
{/* Template */}
7891
<label className="space-y-2">
7992
<div className="font-medium">Template</div>
@@ -182,59 +195,63 @@ export default function ConfigurePage() {
182195
</form>
183196
</div>
184197

185-
{/* ====== Options (auto-updated by chat) ====== */}
186-
<div className="grid gap-3">
187-
<label className="grid gap-1">
188-
<span className="text-sm font-medium">Node version</span>
189-
<input
190-
value={pipeline.options?.nodeVersion ?? ""}
191-
onChange={(e) => pipeline.setOption?.("nodeVersion", e.target.value)}
192-
className="rounded-md border px-3 py-2"
193-
/>
194-
</label>
195-
<label className="grid gap-1">
196-
<span className="text-sm font-medium">Install command</span>
197-
<input
198-
value={pipeline.options?.installCmd ?? ""}
199-
onChange={(e) => pipeline.setOption?.("installCmd", e.target.value)}
200-
className="rounded-md border px-3 py-2"
201-
/>
202-
</label>
203-
<label className="grid gap-1">
204-
<span className="text-sm font-medium">Test command</span>
205-
<input
206-
value={pipeline.options?.testCmd ?? ""}
207-
onChange={(e) => pipeline.setOption?.("testCmd", e.target.value)}
208-
className="rounded-md border px-3 py-2"
209-
/>
210-
</label>
198+
{pipeline.provider === "aws" && (
199+
<>
200+
{/* ====== Options (auto-updated by chat) ====== */}
201+
<div className="grid gap-3">
202+
<label className="grid gap-1">
203+
<span className="text-sm font-medium">Node version</span>
204+
<input
205+
value={pipeline.options?.nodeVersion ?? ""}
206+
onChange={(e) => pipeline.setOption?.("nodeVersion", e.target.value)}
207+
className="rounded-md border px-3 py-2"
208+
/>
209+
</label>
210+
<label className="grid gap-1">
211+
<span className="text-sm font-medium">Install command</span>
212+
<input
213+
value={pipeline.options?.installCmd ?? ""}
214+
onChange={(e) => pipeline.setOption?.("installCmd", e.target.value)}
215+
className="rounded-md border px-3 py-2"
216+
/>
217+
</label>
218+
<label className="grid gap-1">
219+
<span className="text-sm font-medium">Test command</span>
220+
<input
221+
value={pipeline.options?.testCmd ?? ""}
222+
onChange={(e) => pipeline.setOption?.("testCmd", e.target.value)}
223+
className="rounded-md border px-3 py-2"
224+
/>
225+
</label>
226+
<label className="grid gap-1">
227+
<span className="text-sm font-medium">Build command</span>
228+
<input
229+
value={pipeline.options?.buildCmd ?? ""}
230+
onChange={(e) => pipeline.setOption?.("buildCmd", e.target.value)}
231+
className="rounded-md border px-3 py-2"
232+
/>
233+
</label>
234+
</div>
235+
236+
{/* ====== AWS Role ====== */}
211237
<label className="grid gap-1">
212-
<span className="text-sm font-medium">Build command</span>
213-
<input
214-
value={pipeline.options?.buildCmd ?? ""}
215-
onChange={(e) => pipeline.setOption?.("buildCmd", e.target.value)}
216-
className="rounded-md border px-3 py-2"
217-
/>
238+
<span className="text-sm font-medium">AWS Role (OIDC)</span>
239+
<select
240+
disabled={busy}
241+
value={pipeline.options?.awsRoleArn ?? ""}
242+
onChange={(e) => pipeline.setOption?.("awsRoleArn", e.target.value)}
243+
className="rounded-md border px-3 py-2 text-white bg-black"
244+
>
245+
<option value="">-- select --</option>
246+
{pipeline.roles?.map((r: any) => (
247+
<option key={r.arn} value={r.arn}>
248+
{r.name}
249+
</option>
250+
))}
251+
</select>
218252
</label>
219-
</div>
220-
221-
{/* ====== AWS Role ====== */}
222-
<label className="grid gap-1">
223-
<span className="text-sm font-medium">AWS Role (OIDC)</span>
224-
<select
225-
disabled={busy}
226-
value={pipeline.options?.awsRoleArn ?? ""}
227-
onChange={(e) => pipeline.setOption?.("awsRoleArn", e.target.value)}
228-
className="rounded-md border px-3 py-2 text-white bg-black"
229-
>
230-
<option value="">-- select --</option>
231-
{pipeline.roles?.map((r: any) => (
232-
<option key={r.arn} value={r.arn}>
233-
{r.name}
234-
</option>
235-
))}
236-
</select>
237-
</label>
253+
</>
254+
)}
238255

239256
{/* ====== Actions ====== */}
240257
<div className="flex gap-3">

client/src/store/usePipelineStore.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type PipelineState = {
1515
buildCmd: string;
1616
awsRoleArn?: string;
1717
};
18+
provider: "aws" | "jenkins";
1819

1920
// outputs from MCP
2021
result?: McpPipeline;
@@ -30,6 +31,7 @@ type PipelineState = {
3031

3132
type PipelineActions = {
3233
setTemplate(t: string): void;
34+
setProvider(p: "aws" | "jenkins"): void;
3335
toggleStage(s: Stage): void;
3436
setOption<K extends keyof PipelineState["options"]>(k: K, v: PipelineState["options"][K]): void;
3537

@@ -52,6 +54,7 @@ const initial: PipelineState = {
5254
testCmd: "npm test",
5355
buildCmd: "npm run build",
5456
},
57+
provider: "aws",
5558
roles: [],
5659
editing: false,
5760
status: "idle",
@@ -61,6 +64,7 @@ export const usePipelineStore = create<PipelineState & PipelineActions>()((set,
6164
...initial,
6265

6366
setTemplate: (t) => set({ template: t }),
67+
setProvider: (p) => set({ provider: p }),
6468
toggleStage: (s) => {
6569
const cur = get().stages;
6670
set({ stages: cur.includes(s) ? cur.filter(x => x !== s) : [...cur, s] });
@@ -103,13 +107,19 @@ export const usePipelineStore = create<PipelineState & PipelineActions>()((set,
103107
async regenerate({ repo, branch }) {
104108
set({ status: "loading", error: undefined });
105109
try {
106-
const { template, stages, options } = get();
110+
const { template, stages, options, provider } = get();
107111
const res = await api.createPipeline({
108112
repo,
109113
branch,
110114
service: "ci-cd-generator",
115+
provider,
111116
template,
112-
options: { ...options, stages },
117+
node_version: options.nodeVersion,
118+
install_command: options.installCmd,
119+
test_command: options.testCmd,
120+
build_command: options.buildCmd,
121+
aws_role_arn: options.awsRoleArn,
122+
stages,
113123
});
114124

115125
const generated_yaml =

server/server.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ app.use('/mcp/v1', pipelineCommitRouter);
6565
app.use('/mcp/v1', mcpRouter);
6666
app.use('/auth/github', githubAuthRouter);
6767
app.use(authRouter);
68-
app.use('/auth/aws', authAws);
68+
// not currently using
69+
// app.use('/auth/aws', authAws);
6970
app.use('/auth/google', authGoogle);
7071
app.use('/jenkins', jenkinsRouter);
7172
app.use('/pipeline-sessions', pipelineSessionsRouter);

0 commit comments

Comments
 (0)