Files
setup-zig/src/download.ts
2024-12-28 12:23:25 +13:00

113 lines
3.0 KiB
TypeScript

import * as tc from '@actions/tool-cache'
import * as core from '@actions/core'
import * as util from './util'
import * as httpm from '@actions/http-client'
/**
* Download a specific version of the Zig.
* @param version The version to download
* @returns {Promise<string>} Returns the path of the downloaded zig binary
*/
export async function download(version: string): Promise<string> {
const platform = util.getZigPlatform()
const architecture = util.getZigArchitecture()
const extension = util.getPlatformExtension()
const findCachedPath = tc.find('zig', version)
if (findCachedPath !== '') {
core.info(`Using cached Zig ${version} (${platform}, ${architecture})`)
return findCachedPath
}
let ver: string | undefined
if (version == '') {
ver = await getLatestVersion()
}
const url = `https://ziglang.org/download/${ver}/zig-${platform}-${architecture}-${ver}.${extension}`
core.info(
`Downloading Zig ${version} (${platform}, ${architecture}) from ${url} ...`
)
const archivePath = await tc.downloadTool(url)
core.info(`Extracting Zig archive...`)
let extractedPath
if (platform == 'windows') {
extractedPath = await tc.extractZip(archivePath)
} else {
extractedPath = await tc.extractTar(archivePath)
}
const cachedPath = await tc.cacheDir(extractedPath, 'zig', version)
return cachedPath
}
export async function getLatestVersion(): Promise<string> {
const http = new httpm.HttpClient('siteorg/setup-zig')
const url = 'https://ziglang.org/download/index.json'
const response = await http.getJson(url)
if (!(response.statusCode == 200)) {
throw new Error(`API request failed with status ${response.statusCode}`)
}
const responseData = response.result
if (responseData == null) {
throw new Error('No releases found.')
}
const tarballUrls = extractTarballUrls(responseData)
const versions: string[] = []
for (const key in tarballUrls) {
versions.push(key)
}
return versions.reduce((latest, current) =>
compareVersions(latest, current) > 0 ? latest : current
)
}
function extractTarballUrls(data: object): Record<string, string[]> {
const versions = Object.keys(data).filter(version => version !== 'master')
const urls: Record<string, string[]> = {}
for (const version of versions) {
const tarballs: string[] = []
const versionData = (data as any)[version] // eslint-disable-line
for (const key in versionData) {
// eslint-disable-next-line
if (versionData[key]?.tarball) {
tarballs.push(versionData[key].tarball) // eslint-disable-line
}
}
urls[version] = tarballs
}
return urls
}
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number)
const v2Parts = v2.split('.').map(Number)
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0
const part2 = v2Parts[i] || 0
if (part1 > part2) return 1
if (part1 < part2) return -1
}
return 0
}