-
-
Notifications
You must be signed in to change notification settings - Fork 517
Expand file tree
/
Copy pathtrigger-bundle.ts
More file actions
151 lines (130 loc) · 5.52 KB
/
trigger-bundle.ts
File metadata and controls
151 lines (130 loc) · 5.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// api/trigger-bundle.ts
// Triggers the on-demand bundle generation GitHub Actions workflow
export default async function handler(req: any, res: any) {
// Only allow POST requests
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const rawRepoUrl = req.body.repoUrl;
const repoUrl = rawRepoUrl ? rawRepoUrl.trim() : rawRepoUrl;
// Validate input
if (!repoUrl) {
return res.status(400).json({ error: 'Repository URL is required' });
}
// Validate GitHub URL format
// Allow optional trailing slash and .git extension
const githubUrlPattern = /^https?:\/\/(www\.)?github\.com\/([^\/]+)\/([^\/]+)(\.git)?\/?$/;
const match = repoUrl.match(githubUrlPattern);
if (!match) {
return res.status(400).json({
error: 'Invalid GitHub URL format. Expected: https://github.com/owner/repo'
});
}
const owner = match[2];
const repo = match[3].replace('.git', '');
try {
// Check if repository exists
const repoCheckResponse = await fetch(`https://api.github.com/repos/${owner}/${repo}`);
if (!repoCheckResponse.ok) {
if (repoCheckResponse.status === 404) {
return res.status(404).json({ error: 'Repository not found or is private' });
}
throw new Error('Failed to verify repository');
}
const repoData = await repoCheckResponse.json();
// Check repository size (warn if > 1GB)
const sizeInMB = repoData.size / 1024;
if (sizeInMB > 1000) {
return res.status(400).json({
error: `Repository is too large (${sizeInMB.toFixed(0)}MB). Maximum supported size is 1GB.`,
size_mb: sizeInMB
});
}
// Check if bundle already exists in manifest
try {
const manifestResponse = await fetch(
`https://github.com/${process.env.GITHUB_REPOSITORY || 'CodeGraphContext/CodeGraphContext'}/releases/download/on-demand-bundles/manifest.json`
);
if (manifestResponse.ok) {
const manifest = await manifestResponse.json();
const existingBundle = manifest.bundles?.find(
(b: any) => b.repo === `${owner}/${repo}`
);
if (existingBundle) {
// Bundle already exists, return it
return res.status(200).json({
status: 'exists',
message: 'Bundle already exists',
bundle: existingBundle,
download_url: existingBundle.download_url
});
}
}
} catch (err) {
// Manifest doesn't exist yet, continue
console.log('Manifest not found, will create new bundle');
}
// Trigger GitHub Actions workflow
const workflowResponse = await fetch(
`https://api.github.com/repos/${process.env.GITHUB_REPOSITORY || 'CodeGraphContext/CodeGraphContext'}/actions/workflows/generate-bundle-on-demand.yml/dispatches`,
{
method: 'POST',
headers: {
'Authorization': `token ${process.env.GITHUB_TOKEN}`,
'Content-Type': 'application/json',
'Accept': 'application/vnd.github.v3+json'
},
body: JSON.stringify({
ref: 'main',
inputs: {
repo_url: repoUrl,
repo_owner: owner,
repo_name: repo
}
})
}
);
if (!workflowResponse.ok) {
const errorData = await workflowResponse.text();
console.error('GitHub API Error:', errorData);
throw new Error(`Failed to trigger workflow: ${workflowResponse.statusText}`);
}
// Get the latest workflow run ID (we just triggered it)
// Wait a bit for GitHub to register the run
await new Promise(resolve => setTimeout(resolve, 2000));
const runsResponse = await fetch(
`https://api.github.com/repos/${process.env.GITHUB_REPOSITORY || 'CodeGraphContext/CodeGraphContext'}/actions/workflows/generate-bundle-on-demand.yml/runs?per_page=1`,
{
headers: {
'Authorization': `token ${process.env.GITHUB_TOKEN}`,
'Accept': 'application/vnd.github.v3+json'
}
}
);
let runId = null;
let runUrl = null;
if (runsResponse.ok) {
const runsData = await runsResponse.json();
if (runsData.workflow_runs && runsData.workflow_runs.length > 0) {
runId = runsData.workflow_runs[0].id;
runUrl = runsData.workflow_runs[0].html_url;
}
}
return res.status(202).json({
status: 'triggered',
message: 'Bundle generation started',
repository: `${owner}/${repo}`,
repo_size_mb: sizeInMB.toFixed(2),
estimated_time: '5-10 minutes',
run_id: runId,
run_url: runUrl,
status_url: `/api/bundle-status?repo=${owner}/${repo}`
});
} catch (err: any) {
console.error('Error triggering bundle generation:', err);
return res.status(500).json({
error: 'Failed to trigger bundle generation',
details: err.message
});
}
}