Skip to content

Commit d71ffb8

Browse files
authored
Merge pull request #22 from oslabs-beta/lorenc-ci
implement pipeline_version endpoint / rollback feature
2 parents 2628b35 + d13d3b4 commit d71ffb8

File tree

1 file changed

+150
-4
lines changed

1 file changed

+150
-4
lines changed

server/routes/pipelineCommit.js

Lines changed: 150 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,12 @@ router.get('/pipeline_history', requireSession, async (req, res) => {
123123
if (!repoFullName) {
124124
return res
125125
.status(400)
126-
.json({ error: 'repoFUllName query param is required' });
126+
.json({ error: 'repoFullName query param is required' });
127127
}
128128

129129
const userId = req.user?.user_id;
130130
if (!userId) {
131-
return res
132-
.status(400)
133-
.json({ error: 'userId session missing or invalid' });
131+
return res.status(401).json({ error: 'User session missing or invalid' });
134132
}
135133

136134
const branchName = branch || 'main';
@@ -172,4 +170,152 @@ router.get('/pipeline_history', requireSession, async (req, res) => {
172170
}
173171
});
174172

173+
/**
174+
* POST /mcp/v1/pipeline_rollback
175+
* Body:
176+
* { "versionId": "<pipeline_versions.id>" }
177+
*
178+
* Restores an older YAML version from pipeline_versions by:
179+
* - fetching the yaml for that version
180+
* - re-committing it to GitHub at workflow_path on branch
181+
* - logging a deployment_logs row with action='pipeline_rollback'
182+
* - saving a new pipeline_versions entry with source='pipeline_rollback'
183+
*/
184+
185+
router.post('/pipeline_rollback', requireSession, async (req, res) => {
186+
try {
187+
const { versionId } = req.body || {};
188+
if (!versionId) {
189+
return res
190+
.status(400)
191+
.json({ error: 'Missing versionId from request body' });
192+
}
193+
194+
const userId = req.user?.user_id;
195+
if (!userId) {
196+
return res.status(401).json({ error: 'User session missing or invalid' });
197+
}
198+
199+
// Look up the pipeline version we want to restore
200+
201+
const versionResult = await query(
202+
`
203+
select
204+
id,
205+
user_id,
206+
repo_full_name,
207+
branch,
208+
workflow_path,
209+
yaml,
210+
yaml_hash,
211+
source,
212+
created_at
213+
from pipeline_versions
214+
where id = $1
215+
limit 1;
216+
`,
217+
[versionId]
218+
);
219+
220+
if (!versionResult.rowCount || !versionResult.rows.length) {
221+
return res
222+
.status(404)
223+
.json({ error: 'Pipeline version not found for give versionId' });
224+
}
225+
226+
const version = versionResult.rows[0];
227+
const {
228+
repo_full_name: repoFullName,
229+
branch,
230+
workflow_path: workflowPath,
231+
yaml,
232+
} = version;
233+
234+
// Get github token for this user
235+
const token = await getGithubAccessTokenForUser(userId);
236+
if (!token) {
237+
return res
238+
.status(401)
239+
.json({ error: 'Missing GitHub token for this user' });
240+
}
241+
242+
const [owner, repo] = (repoFullName || '').split('/');
243+
if (!owner || !repo) {
244+
return res
245+
.status(400)
246+
.json({ error: `Invalid repo_full_name on version ${versionId}` });
247+
}
248+
249+
//Re-commit the yaml file to GitHub (overwrite current workflow)
250+
const githubResult = await upsertWorkflowFile({
251+
token,
252+
owner,
253+
repo,
254+
path: workflowPath,
255+
content: yaml,
256+
branch,
257+
message: `Rollback pipeline to version ${versionId}`,
258+
});
259+
260+
// Log into deployment_log as a pipeline_rollback
261+
const deploymentResult = await query(
262+
`
263+
INSERT INTO deployment_logs
264+
(user_id, provider, repo_full_name, environment, branch, action,
265+
status, started_at, summary, metadata)
266+
VALUES ($1, $2, $3, $4, $5, $6,
267+
'success', NOW(), $7, $8::jsonb)
268+
returning *;
269+
`,
270+
[
271+
userId,
272+
'github_actions',
273+
repoFullName,
274+
'global',
275+
branch,
276+
'pipeline_rollback',
277+
`Rolled back pipeline to version ${versionId}`,
278+
JSON.stringify({
279+
workflow_path: workflowPath,
280+
branch,
281+
version_id: versionId,
282+
commit_sha: githubResult?.commit?.sha || null,
283+
commit_url: githubResult?.commit?.html_url || null,
284+
source: 'pipeline_rollback',
285+
}),
286+
]
287+
);
288+
289+
const deployment = deploymentResult.rows[0];
290+
291+
// Save a new pipelone_versions entry representing this rollback operation
292+
await savePipelineVersion({
293+
userId,
294+
repoFullName,
295+
branch,
296+
workflowPath,
297+
yaml,
298+
source: 'pipeline_rollback',
299+
});
300+
301+
return res.status(201).json({
302+
ok: true,
303+
message: 'Pipeline rolled back successfully',
304+
data: {
305+
github: githubResult,
306+
deployment,
307+
},
308+
});
309+
} catch (err) {
310+
console.error('[pipeline_rollback] error:', err);
311+
const status = err.status || 500;
312+
return res
313+
.status(status)
314+
.json({
315+
error: err.message || 'Failed to rollback pipeline',
316+
details: err.details || undefined,
317+
});
318+
}
319+
});
320+
175321
export default router;

0 commit comments

Comments
 (0)