Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
tjjfvi committed Mar 20, 2023
1 parent 9d71c31 commit 377b79e
Showing 1 changed file with 29 additions and 17 deletions.
46 changes: 29 additions & 17 deletions server/capi.dev/delegator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@ import { f, handleErrors } from "../mod.ts"

serve(handleErrors(handler))

const delegateeProjectId = "70eddd08-c9b0-4cb3-b100-8c6facf52f1e"

const ttl = 60_000
const shaAbbrevLength = 8

const GITHUB_API_REPO = "https://api.github.com/repos/paritytech/capi"

const rTagVersion = /^v(\d+\.\d+\.\d+(?:-.+)?)$/
const rPrVersion = /^pr:(\d+)$/

const rVersionedUrl = /^(?:\/@(.+?))?(\/.*)?$/

const delegateeProjectId = "70eddd08-c9b0-4cb3-b100-8c6facf52f1e"
const githubApiBase = "https://api.github.com/repos/paritytech/capi"

const { signal } = new AbortController()

async function handler(request: Request) {
const url = new URL(request.url)
const [, version, path = "/"] = rVersionedUrl.exec(url.pathname)!
if (!version) throw f.notFound()
if (!version) return f.redirect(`/@${await defaultVersion()}${path}`)
const sha = await getSha(version)
let normalizedVersion
if (rTagVersion.test(version)) {
Expand All @@ -39,37 +38,42 @@ async function handler(request: Request) {
})
}

const shaTtl = 60_000
const shaMemo = new TimedMemo<string, string>(shaTtl, signal)
const defaultVersionMemo = new TimedMemo<void, string>(ttl, signal)
async function defaultVersion() {
return await defaultVersionMemo.run(undefined, async () => {
const release = (await github<GithubRelease>(`releases/latest`))
?? (await github<GithubRelease[]>(`releases`))[0]
return release.tag_name
})
}

const shaMemo = new TimedMemo<string, string>(ttl, signal)
async function getSha(version: string): Promise<string> {
const ref = version
.replace(rPrVersion, "pull/$1/head")
.replace(rTagVersion, "v$1")
.replace(/:/g, "/")
return await shaMemo.run(
ref,
async () => (await json(`${GITHUB_API_REPO}/commits/${ref}`)).sha,
async () => (await github<GithubCommit>(`commits/${ref}`)).sha,
)
}

const deploymentTtl = 60_000
const deploymentMemo = new TimedMemo<string, string>(deploymentTtl, signal)
const deploymentMemo = new TimedMemo<string, string>(ttl, signal)
async function getDeployment(sha: string) {
return await deploymentMemo.run(sha, async () => {
const deployments: GithubDeployment[] = await json(
`${GITHUB_API_REPO}/deployments?sha=${sha}`,
)
const deployments = await github<GithubDeployment[]>(`deployments?sha=${sha}`)
const deployment = deployments.find((x) => x.payload.project_id === delegateeProjectId)
if (!deployment) throw f.notFound()
const statuses: GithubStatus[] = await json(deployment.statuses_url)
const statuses = await github<GithubStatus[]>(deployment.statuses_url)
const url = statuses.map((x) => x.environment_url).find((x) => x)
if (!url) throw f.notFound()
return url
})
}

async function json(url: string) {
const response = await fetch(url)
async function github<T>(url: string): Promise<T> {
const response = await fetch(new URL(url, githubApiBase))
if (!response.ok) throw new Error(`${url}: invalid response`)
return await response.json()
}
Expand All @@ -82,3 +86,11 @@ interface GithubDeployment {
interface GithubStatus {
environment_url?: string
}

interface GithubRelease {
tag_name: string
}

interface GithubCommit {
sha: string
}

0 comments on commit 377b79e

Please sign in to comment.