Skip to content

Commit b199b34

Browse files
committed
fix(worker): prefer vercel.app preview url for discord
1 parent 3c28fa2 commit b199b34

File tree

1 file changed

+121
-21
lines changed

1 file changed

+121
-21
lines changed

.github/scripts/ai-inspector-worker.mjs

Lines changed: 121 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ const getPreviewUrlFromGitHubCommitStatus = async (token, owner, repo, commitSha
403403
const pollingIntervalMs = Number.isFinite(intervalMs) && intervalMs > 0 ? intervalMs : 10000;
404404
const pollingTimeoutMs = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : 240000;
405405
const deadline = Date.now() + pollingTimeoutMs;
406+
let lastKnownVercelUrl = "";
406407

407408
while (Date.now() < deadline) {
408409
const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/commits/${commitSha}/status`, {
@@ -420,23 +421,123 @@ const getPreviewUrlFromGitHubCommitStatus = async (token, owner, repo, commitSha
420421

421422
const data = await response.json();
422423
const statuses = Array.isArray(data?.statuses) ? data.statuses : [];
423-
const urlStatus =
424-
statuses.find((status) => typeof status?.target_url === "string" && status.target_url.includes("vercel.app")) ??
425-
statuses.find(
426-
(status) =>
427-
typeof status?.context === "string" &&
428-
status.context.toLowerCase().includes("vercel") &&
429-
typeof status?.target_url === "string",
430-
);
431-
432-
if (urlStatus?.target_url) {
433-
return urlStatus.target_url;
424+
const deploymentUrlStatus = statuses.find(
425+
(status) => typeof status?.target_url === "string" && status.target_url.includes("vercel.app"),
426+
);
427+
if (deploymentUrlStatus?.target_url) {
428+
return deploymentUrlStatus.target_url;
429+
}
430+
431+
const vercelStatus = statuses.find(
432+
(status) =>
433+
typeof status?.context === "string" &&
434+
status.context.toLowerCase().includes("vercel") &&
435+
typeof status?.target_url === "string",
436+
);
437+
if (vercelStatus?.target_url) {
438+
lastKnownVercelUrl = vercelStatus.target_url;
434439
}
435440

436441
await sleep(pollingIntervalMs);
437442
}
438443

439-
return "";
444+
return lastKnownVercelUrl;
445+
};
446+
447+
const getPreviewUrlFromGitHubPrComments = async (token, owner, repo, prNumber) => {
448+
const intervalMs = Number(process.env.AI_INSPECTOR_VERCEL_PREVIEW_INTERVAL_MS ?? "10000");
449+
const timeoutMs = Number(process.env.AI_INSPECTOR_VERCEL_PREVIEW_TIMEOUT_MS ?? "240000");
450+
const pollingIntervalMs = Number.isFinite(intervalMs) && intervalMs > 0 ? intervalMs : 10000;
451+
const pollingTimeoutMs = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : 240000;
452+
const deadline = Date.now() + pollingTimeoutMs;
453+
const vercelUrlPattern = /https:\/\/[^\s)]+\.vercel\.app[^\s)]*/gi;
454+
let lastKnownVercelUrl = "";
455+
456+
while (Date.now() < deadline) {
457+
const response = await fetch(
458+
`https://api.github.com/repos/${owner}/${repo}/issues/${prNumber}/comments?per_page=50`,
459+
{
460+
headers: {
461+
Accept: "application/vnd.github+json",
462+
Authorization: `Bearer ${token}`,
463+
"X-GitHub-Api-Version": "2022-11-28",
464+
},
465+
},
466+
);
467+
468+
if (!response.ok) {
469+
const body = await response.text();
470+
throw new Error(`Failed to fetch PR comments from GitHub (${response.status}): ${body}`);
471+
}
472+
473+
const comments = await response.json();
474+
if (Array.isArray(comments)) {
475+
for (const comment of comments) {
476+
const body = typeof comment?.body === "string" ? comment.body : "";
477+
const matches = body.match(vercelUrlPattern);
478+
if (matches && matches.length > 0) {
479+
lastKnownVercelUrl = matches[0];
480+
if (lastKnownVercelUrl.includes(".vercel.app")) {
481+
return lastKnownVercelUrl;
482+
}
483+
}
484+
}
485+
}
486+
487+
await sleep(pollingIntervalMs);
488+
}
489+
490+
return lastKnownVercelUrl;
491+
};
492+
493+
const normalizePreviewUrl = (url) => {
494+
if (!url) {
495+
return "";
496+
}
497+
498+
const trimmed = url.trim();
499+
if (!trimmed) {
500+
return "";
501+
}
502+
503+
if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
504+
return trimmed;
505+
}
506+
507+
if (trimmed.includes(".")) {
508+
return `https://${trimmed}`;
509+
}
510+
511+
return trimmed;
512+
};
513+
514+
const resolvePreviewUrl = async ({ token, owner, repo, branchName, commitSha, prNumber }) => {
515+
const templateUrl = normalizePreviewUrl(getPreviewUrl(branchName));
516+
517+
try {
518+
const vercelApiUrl = normalizePreviewUrl(await getPreviewUrlFromVercel(branchName));
519+
if (vercelApiUrl) {
520+
return vercelApiUrl;
521+
}
522+
523+
const commitStatusUrl = normalizePreviewUrl(await getPreviewUrlFromGitHubCommitStatus(token, owner, repo, commitSha));
524+
if (commitStatusUrl.includes(".vercel.app")) {
525+
return commitStatusUrl;
526+
}
527+
528+
const commentUrl = normalizePreviewUrl(await getPreviewUrlFromGitHubPrComments(token, owner, repo, prNumber));
529+
if (commentUrl) {
530+
return commentUrl;
531+
}
532+
533+
if (commitStatusUrl) {
534+
return commitStatusUrl;
535+
}
536+
} catch (previewError) {
537+
console.error("Preview URL resolution failed", previewError);
538+
}
539+
540+
return templateUrl;
440541
};
441542

442543
const applyPatch = (patch) => {
@@ -606,15 +707,14 @@ const main = async () => {
606707

607708
const prUrl = pr.html_url;
608709
const commitSha = runGitOutput(["rev-parse", "HEAD"]).trim();
609-
let previewUrl = getPreviewUrl(branchName);
610-
try {
611-
previewUrl =
612-
(await getPreviewUrlFromVercel(branchName)) ||
613-
(await getPreviewUrlFromGitHubCommitStatus(githubToken, owner, repoName, commitSha)) ||
614-
previewUrl;
615-
} catch (previewError) {
616-
console.error(`Task ${taskId} preview URL resolution failed`, previewError);
617-
}
710+
const previewUrl = await resolvePreviewUrl({
711+
token: githubToken,
712+
owner,
713+
repo: repoName,
714+
branchName,
715+
commitSha,
716+
prNumber: pr.number,
717+
});
618718

619719
await taskRef.update({
620720
status: "completed",

0 commit comments

Comments
 (0)