UNPKG

@reliverse/rse-sdk

Version:

@reliverse/rse-sdk allows you to create new plugins for @reliverse/rse CLI, interact with reliverse.org, and even extend your own CLI functionality (you may also try @reliverse/dler-sdk for this case).

161 lines (160 loc) 5.3 kB
import { relinka, relinkaAsync } from "@reliverse/relinka"; import { deploymentsCreateDeployment } from "@vercel/sdk/funcs/deploymentsCreateDeployment"; import { deploymentsGetDeployment } from "@vercel/sdk/funcs/deploymentsGetDeployment"; import { deploymentsGetDeploymentEvents } from "@vercel/sdk/funcs/deploymentsGetDeploymentEvents"; import { simpleGit } from "simple-git"; import { withRateLimit } from "./vercel-api.js"; import { getPrimaryVercelTeam } from "./vercel-team.js"; export async function monitorDeployment(vercelInstance, deploymentId, teamId, slug, showDetailedLogs = false) { try { const logsRes = await deploymentsGetDeploymentEvents(vercelInstance, { idOrUrl: deploymentId, teamId, slug }); if (!logsRes.ok) throw logsRes.error; const logs = logsRes.value; if (Array.isArray(logs)) { let errors = 0; let warnings = 0; for (const log of logs) { const timestamp = new Date(log.created).toLocaleTimeString(); const message = `[${log.type}] ${log.text}`; if (log.type === "error") { errors++; relinka("error", `${timestamp}: ${message}`); } else if (log.type === "warning") { warnings++; relinka("warn", `${timestamp}: ${message}`); } else if (showDetailedLogs) { relinka("info", `${timestamp}: ${message}`); } } if (errors > 0 || warnings > 0) { relinka( "info", `Deployment summary: ${errors} errors, ${warnings} warnings` ); } } } catch (error) { relinka( "error", "Error monitoring deployment:", error instanceof Error ? error.message : String(error) ); } } export async function createInitialVercelDeployment(githubInstance, vercelInstance, projectId, memory, projectName, config, selectedOptions, githubUsername, githubToken) { if (!githubToken) { throw new Error( "GitHub token not found in rse's memory. Please restart the CLI and try again. Notify the @reliverse/rse developers if the problem persists." ); } relinka("info", "Creating the initial deployment..."); relinka("verbose", "Using Vercel deployment config:", JSON.stringify(config)); const vercelTeam = await getPrimaryVercelTeam(vercelInstance, memory); if (!vercelTeam) throw new Error("No Vercel team found."); const teamId = vercelTeam.id; const slug = vercelTeam.slug; const git = simpleGit(); let commitSha; try { commitSha = await git.revparse(["HEAD"]); } catch (error) { throw new Error( `Failed to get local commit SHA. Ensure the repository is not empty. ${error}` ); } let numericRepoId; try { const repoResp = await githubInstance.rest.repos.get({ owner: githubUsername, repo: projectName }); numericRepoId = repoResp.data.id; } catch (error) { throw new Error(`Failed to fetch GitHub repository numeric ID. ${error}`); } const deploymentRes = await withRateLimit(async () => { return await deploymentsCreateDeployment(vercelInstance, { teamId, slug, requestBody: { name: projectName, target: "production", project: projectId, gitSource: { type: "github", ref: "main", repoId: numericRepoId, sha: commitSha } } }); }); if (!deploymentRes.ok) throw deploymentRes.error; const deployment = deploymentRes.value; if (!deployment?.id || !deployment.readyState || !deployment.url) { throw new Error( "Failed to create deployment: invalid response from Vercel" ); } const inProgressStates = ["BUILDING", "INITIALIZING", "QUEUED"]; const deploymentUrl = slug ? `https://vercel.com/${slug}/${projectName}/${deployment.id}` : "https://vercel.com"; relinka( "info", `Deployment started. To monitor progress, visit: ${deploymentUrl}`, "Status messages will appear every 10 seconds." ); let lastMessageTime = Date.now(); let status = deployment.readyState; while (inProgressStates.includes(status)) { await monitorDeployment( vercelInstance, deployment.id, teamId, slug, selectedOptions.includes("monitoring") ); await new Promise((resolve) => setTimeout(resolve, 5e3)); const depRes = await withRateLimit(async () => { return await deploymentsGetDeployment(vercelInstance, { idOrUrl: deployment.id, teamId, slug }); }); if (!depRes.ok) throw depRes.error; status = depRes.value.readyState; const now = Date.now(); if (now - lastMessageTime >= 1e4) { await relinkaAsync( "info", `Deployment status: ${status}`, void 0, void 0, { delay: 50, useSpinner: true, spinnerDelay: 50 } ); lastMessageTime = now; } } if (status !== "READY") { await monitorDeployment( vercelInstance, deployment.id, teamId, slug, selectedOptions.includes("monitoring") ); throw new Error(`Deployment failed with status: ${status}`); } await monitorDeployment( vercelInstance, deployment.id, teamId, slug, selectedOptions.includes("monitoring") ); return { url: deployment.url, id: deployment.id }; }