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} Returns the path of the downloaded zig binary */ export async function download(version: string): Promise { 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 { 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 { const versions = Object.keys(data).filter(version => version !== 'master') const urls: Record = {} 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 }