diff --git a/lib/main.js b/lib/main.js index 8274253a..2f1e2a63 100644 --- a/lib/main.js +++ b/lib/main.js @@ -67,7 +67,9 @@ function run() { const cacheEnabled = (core.getInput("cache") === "enable") && tag !== "latest" && tag !== ""; - const [owner, project] = repo.split("/"); + const [owner, repoName] = repo.split("/"); + // If a project name was manually configured, use it + const assetName = core.getInput("asset-name"); let osMatch = []; // Determine Platform let osPlatform = core.getInput("platform"); @@ -90,24 +92,25 @@ function run() { osMatch.push(osPlatform); core.info(`==> System reported platform: ${os.platform()}`); core.info(`==> Using platform: ${osPlatform}`); + const osArchMatch = []; // Determine Architecture let osArch = core.getInput("arch"); if (osArch === "") { osArch = os.arch(); switch (os.arch()) { case "x64": - osMatch.push("x86_64", "x64", "amd64"); + osArchMatch.push("x86_64", "x64", "amd64"); break; case "arm64": - osMatch.push("aarch64", "arm64"); + osArchMatch.push("aarch64", "arm64"); break; default: - osMatch.push(os.arch()); + osArchMatch.push(os.arch()); break; } } else { - osMatch.push(osArch); + osArchMatch.push(osArch); } core.info(`==> System reported arch: ${os.arch()}`); core.info(`==> Using arch: ${osArch}`); @@ -138,8 +141,9 @@ function run() { core.info(`==> Will chmod downloaded release asset to ${chmodTo}`); } let toolInfo = { - owner: owner, - project: project, + owner, + repoName, + assetName, tag: tag, osArch: osArch, osPlatform: osPlatform @@ -160,7 +164,7 @@ function run() { if (cacheEnabled && cacheKey !== undefined) { let ok = yield cache.restoreCache([dest], cacheKey); if (ok !== undefined) { - core.info(`Found ${project} in the cache: ${dest}`); + core.info(`Found ${assetName} in the cache: ${dest}`); core.info(`Adding ${finalBinLocation} to the path`); core.addPath(finalBinLocation); return; @@ -170,29 +174,62 @@ function run() { if (tag === "latest") { getReleaseUrl = yield octokit.rest.repos.getLatestRelease({ owner: owner, - repo: project, + repo: repoName, }); } else { getReleaseUrl = yield octokit.rest.repos.getReleaseByTag({ owner: owner, - repo: project, + repo: repoName, tag: tag, }); } + // Build regular expressions for all the target triple components + // + // See: https://wiki.osdev.org/Target_Triplet + let osArchMatchRegexForm = `(${osArchMatch.join('|')})`; + let osArchRegex = new RegExp(`${osArchMatchRegexForm}`); + let vendorRegex = new RegExp("(apple|linux|pc|unknown)?"); // vendor may not be specified let osMatchRegexForm = `(${osMatch.join('|')})`; - let re = new RegExp(`${osMatchRegexForm}.*${osMatchRegexForm}.*${extMatchRegexForm}`); + let osRegex = new RegExp(`${osMatchRegexForm}`); + let libcRegex = new RegExp("(gnu|glibc|musl)?"); // libc calling convention may not be specified + let extensionRegex = new RegExp(`${extMatchRegexForm}$`); + // Attempt to find the asset, with matches for arch, vendor, os, libc and extension as appropriate let asset = getReleaseUrl.data.assets.find(obj => { - core.info(`searching for ${obj.name} with ${re.source}`); - let normalized_obj_name = obj.name.toLowerCase(); - return re.test(normalized_obj_name); + let normalized = obj.name.toLowerCase(); + core.info(`checking for arch/vendor/os/glibc triple matches for (normalized) asset [${normalized}]`); + const nameIncluded = assetName ? normalized.includes(assetName) : true; + if (!nameIncluded) { + core.debug(`name [${assetName}] wasn't included in [${normalized}]`); + } + const osArchMatches = osArchRegex.test(normalized); + if (!osArchMatches) { + core.debug("osArch didn't match"); + } + const osMatches = osRegex.test(normalized); + if (!osMatches) { + core.debug("os didn't match"); + } + const vendorMatches = vendorRegex.test(normalized); + if (!vendorMatches) { + core.debug("vendor didn't match"); + } + const libcMatches = libcRegex.test(normalized); + if (!libcMatches) { + core.debug("libc calling didn't match"); + } + const extensionMatches = extensionRegex.test(normalized); + if (!extensionMatches) { + core.debug("extenison didn't match"); + } + return nameIncluded && osArchMatches && osMatches && vendorMatches && libcMatches && extensionMatches; }); if (!asset) { const found = getReleaseUrl.data.assets.map(f => f.name); throw new Error(`Could not find a release for ${tag}. Found: ${found}`); } const url = asset.url; - core.info(`Downloading ${project} from ${url}`); + core.info(`Downloading ${assetName} from ${url}`); const binPath = yield tc.downloadTool(url, undefined, `token ${token}`, { accept: 'application/octet-stream' }); @@ -298,7 +335,7 @@ function run() { } core.info(`Adding ${finalBinLocation} to the path`); core.addPath(finalBinLocation); - core.info(`Successfully installed ${project}`); + core.info(`Successfully installed ${assetName}`); core.info(`Binaries available at ${finalBinLocation}`); } catch (error) { @@ -317,10 +354,10 @@ function cachePrimaryKey(info) { return undefined; } return "action-install-gh-release/" + - `${info.owner}/${info.project}/${info.tag}/${info.osPlatform}-${info.osArch}`; + `${info.owner}/${info.assetName}/${info.tag}/${info.osPlatform}-${info.osArch}`; } function toolPath(info) { - return path.join(getCacheDirectory(), info.owner, info.project, info.tag, `${info.osPlatform}-${info.osArch}`); + return path.join(getCacheDirectory(), info.owner, info.assetName, info.tag, `${info.osPlatform}-${info.osArch}`); } function getCacheDirectory() { const cacheDirectory = process.env['RUNNER_TOOL_CACHE'] || '';