113 lines
3.0 KiB
TypeScript
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
|
|
}
|