Files
stablyai--orca/config/scripts/latest-stable-release.mjs
2026-07-13 13:05:33 +08:00

88 lines
2.3 KiB
JavaScript

#!/usr/bin/env node
import { pathToFileURL } from 'node:url'
const API_VERSION = '2022-11-28'
const DESKTOP_STABLE_TAG_PATTERN = /^v([0-9]+)\.([0-9]+)\.([0-9]+)$/
export function parseDesktopStableTag(tag) {
const match = DESKTOP_STABLE_TAG_PATTERN.exec(tag)
if (!match) {
return null
}
return {
tag,
major: Number(match[1]),
minor: Number(match[2]),
patch: Number(match[3])
}
}
export function latestStableDesktopReleaseTag(releases) {
const stableTags = releases
.filter((release) => release?.draft !== true)
.map((release) => parseDesktopStableTag(release?.tag_name ?? release?.tagName ?? ''))
.filter(Boolean)
.sort((a, b) => a.major - b.major || a.minor - b.minor || a.patch - b.patch)
return stableTags.at(-1)?.tag ?? ''
}
async function githubJson(fetchImpl, url, token) {
const res = await fetchImpl(url, {
headers: {
Accept: 'application/vnd.github+json',
Authorization: `Bearer ${token}`,
'X-GitHub-Api-Version': API_VERSION
}
})
if (!res.ok) {
const body = await res.text().catch(() => '')
throw new Error(`GitHub request failed ${res.status} ${res.statusText}: ${body.slice(0, 300)}`)
}
return res.json()
}
export async function fetchReleases(repo, token, fetchImpl = fetch) {
if (!repo) {
throw new Error('repo is required')
}
if (!token) {
throw new Error('token is required')
}
const releases = []
for (let page = 1; ; page += 1) {
const pageReleases = await githubJson(
fetchImpl,
`https://api.github.com/repos/${repo}/releases?per_page=100&page=${page}`,
token
)
if (!Array.isArray(pageReleases)) {
throw new Error(`GitHub releases response page ${page} for ${repo} was not an array`)
}
releases.push(...pageReleases)
if (pageReleases.length < 100) {
break
}
}
return releases
}
async function main() {
const token = process.env.GH_TOKEN || process.env.GITHUB_TOKEN
const repo = process.env.GITHUB_REPOSITORY || 'stablyai/orca'
const releases = await fetchReleases(repo, token)
process.stdout.write(latestStableDesktopReleaseTag(releases))
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
main().catch((error) => {
console.error(error instanceof Error ? error.message : String(error))
process.exit(1)
})
}