diff --git a/.github/scripts/docs/preview-deploy.js b/.github/scripts/docs/preview-deploy.js index 25254c87a46d..8ee07109e9a5 100644 --- a/.github/scripts/docs/preview-deploy.js +++ b/.github/scripts/docs/preview-deploy.js @@ -1,23 +1,33 @@ module.exports = async ({ github, context }) => { - const { VERCEL_TOKEN, VERCEL_TEAM_ID, GITHUB_HEAD_REF } = process.env; - - console.log( - JSON.stringify( - await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - }), - null, - 2 - ) + const { VERCEL_TOKEN, VERCEL_TEAM_ID, GITHUB_SHA } = process.env; + + if (!VERCEL_TOKEN || !VERCEL_TEAM_ID) { + throw new Error( + `cannot run docs preview deploy workflow, ` + + `VERCEL_TOKEN or VERCEL_TEAM_ID secrets are missing` + ); + } + + const existingComments = ( + await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }) + ).data; + + let commentMessage = `# Docs preview deploy\n`; + + const updateComment = existingComments.find( + (c) => + c.performed_via_github_app?.slug === "github-actions" && + c.body?.startsWith(commentMessage) ); - return; - const res = await fetch( - `https://api.vercel.com/v13/deployments?teamId=${VERCEL_TEAM_ID}`, - { - body: JSON.stringify({ + try { + const deployment = await vercelFetch( + "https://api.vercel.com/v13/deployments", + { name: "edgedb-docs", gitSource: { type: "github", @@ -28,28 +38,84 @@ module.exports = async ({ github, context }) => { projectSettings: { buildCommand: `EDGEDB_REPO_BRANCH=${GITHUB_HEAD_REF} yarn vercel-build`, }, - }), + } + ); + + commentMessage += `\nšŸ”„ Deploying docs preview for commit ${GITHUB_SHA.slice( + 0, + 8 + )}:\n\n`; + } catch (e) { + commentMessage += `\nāŒ Failed to deploy docs preview for commit ${GITHUB_SHA.slice( + 0, + 8 + )}:\n\n\`\`\`\n${e.message}\n\`\`\``; + } + + commentMessage += `\n\n(Last updated: ${formatDatetime(new Date())})`; + + if (updateComment) { + github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: updateComment.id, + body: commentMessage, + }); + } else { + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: commentMessage, + }); + } +}; + +async function vercelFetch(url, body) { + const { VERCEL_TOKEN, VERCEL_TEAM_ID } = process.env; + const _url = new URL(url); + url = `${_url.origin}${_url.pathname}?${new URLSearchParams({ + teamId: VERCEL_TEAM_ID, + })}`; + + let res; + try { + res = await fetch(url, { + body: JSON.stringify(body), headers: { Authorization: `Bearer ${VERCEL_TOKEN}`, "Content-Type": "application/json", }, method: "post", - } - ); + }); + } catch (e) { + throw new Error(`vercel api request failed: ${e}`); + } if (res.ok) { - const deployment = await res.json(); - console.log(deployment.url); - - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: `Deployed docs preview: `, - }); + return await res.json(); } else { + let body; + try { + body = await res.text(); + } catch (e) { + // ignore + } throw new Error( - `vercel create deployment api request failed: ${res.status} ${res.statusText}` + `vercel api request failed: ${res.status} ${res.statusText}, ${body}` ); } -}; +} + +function formatDatetime(date) { + return date.toLocaleString("en-US", { + year: "numeric", + month: "short", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", + hourCycle: "h24", + timeZoneName: "short", + }); +}