Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 80 additions & 21 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 62 additions & 18 deletions src/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
RepositorySlug,
SemanticVersion,
Sha1Hash,
TargetDuple,
TargetTriple,
BinaryName,
} from "./types";
Expand Down Expand Up @@ -133,6 +134,7 @@ export async function fetchReleaseAssetMetadataFromTag(
binaryName: Option<BinaryName>,
tag: ExactSemanticVersion,
targetTriple: TargetTriple,
targetDuple: TargetDuple,
): Promise<ReleaseAssetMetadata> {
// Maintainer's note: this impure function call makes this function difficult to test.
const releaseMetadata = await octokit.rest.repos.getReleaseByTag({
Expand All @@ -141,46 +143,88 @@ export async function fetchReleaseAssetMetadataFromTag(
tag,
});

// When the binary name is provided, look for matching binary and target triple.
// When the binary name is provided, look for matching binary with target triple or target duple
if (isSome(binaryName)) {
const targetLabel = `${binaryName.value}-${targetTriple}`;
const asset = releaseMetadata.data.assets.find(
(asset) => asset.label === targetLabel,
);
const targetLabelTraditional = `${binaryName.value}-${targetTriple}`;
const targetLabelDuple = `${binaryName.value}-${targetDuple}`;

const asset = releaseMetadata.data.assets.find((asset) => {
// Check for label match
if (typeof asset.label === "string") {
if (asset.label === targetLabelTraditional || asset.label === targetLabelDuple) {
return true;
}
}

// Check for name match
if (typeof asset.name === "string") {
if (asset.name === targetLabelTraditional || asset.name === targetLabelDuple) {
return true;
}
}

return false;
});

if (asset === undefined) {
throw new Error(
`Expected to find asset in release ${slug.owner}/${slug.repository}@${tag} with label ${targetLabel}`,
`Expected to find asset in release ${slug.owner}/${slug.repository}@${tag} with label or name ${targetLabelTraditional} or ${targetLabelDuple}`,
);
}

return {
binaryName: binaryName,
url: asset.url,
};
}

// When the binary name is not provided, support two use cases:
// When the binary name is not provided, support these use cases:
// 1. There is only one binary uploaded to this release, a named binary.
// 2. There is an asset label matching the target triple (with no binary name).
// 2. There is an asset label matching the target triple or target duple.
// In both cases, we assume that's the binary the user meant.
// If there is ambiguity, exit with an error.
const matchingTargetTriples = releaseMetadata.data.assets.filter(
(asset) =>
typeof asset.label === "string" && asset.label.endsWith(targetTriple),
);
if (matchingTargetTriples.length === 0) {
const matchingAssets = releaseMetadata.data.assets.filter((asset) => {
// Check label match
if (typeof asset.label === "string") {
if (asset.label.endsWith(targetTriple) || asset.label.endsWith(targetDuple)) {
return true;
}
}

// Check name match
if (typeof asset.name === "string") {
if (asset.name.endsWith(targetTriple) || asset.name.endsWith(targetDuple)) {
return true;
}
}

return false;
});

if (matchingAssets.length === 0) {
throw new Error(
`Expected to find asset in release ${slug.owner}/${slug.repository}@${tag} with label ending in ${targetTriple}`,
`Expected to find asset in release ${slug.owner}/${slug.repository}@${tag} with label or name ending in ${targetTriple} or ${targetDuple}`,
);
}
if (matchingTargetTriples.length > 1) {
if (matchingAssets.length > 1) {
throw new Error(
`Ambiguous targets: expected to find a single asset in release ${slug.owner}/${slug.repository}@${tag} matching target triple ${targetTriple}, but found ${matchingTargetTriples.length}.
`Ambiguous targets: expected to find a single asset in release ${slug.owner}/${slug.repository}@${tag} matching target triple ${targetTriple} or target duple ${targetDuple}, but found ${matchingAssets.length}.

To resolve, specify the desired binary with the target format ${slug.owner}/${slug.repository}/<binary-name>@${tag}`,
);
}
const asset = matchingTargetTriples.shift()!;
const targetName = stripTargetTriple(asset.label!);
const asset = matchingAssets.shift()!;

// Determine which field matched to use for stripping the target triple
let matchField: string;
if (typeof asset.label === "string" &&
(asset.label.endsWith(targetTriple) || asset.label.endsWith(targetDuple))) {
matchField = asset.label;
} else {
matchField = asset.name!;
}

const targetName = stripTargetTriple(matchField);
return {
binaryName: targetName,
url: asset.url,
Expand Down
12 changes: 8 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
parseTargetReleases,
parseToken,
} from "./parse";
import { getTargetTriple } from "./platform";
import { getTargetTriple, getTargetDuple } from "./platform";
import {
fetchReleaseAssetMetadataFromTag,
findExactSemanticVersionTag,
Expand Down Expand Up @@ -48,7 +48,10 @@ async function installGitHubReleaseBinary(
token: string,
ignoreExisting: boolean,
): Promise<void> {
const targetTriple = getTargetTriple(arch(), platform());
const currentArch = arch();
const currentPlatform = platform();
const targetTriple = getTargetTriple(currentArch, currentPlatform);
const targetDuple = getTargetDuple(currentArch, currentPlatform);

const releaseTag = await findExactSemanticVersionTag(
octokit,
Expand All @@ -60,8 +63,8 @@ async function installGitHubReleaseBinary(
storageDirectory,
targetRelease.slug,
releaseTag,
platform(),
arch(),
currentPlatform,
currentArch,
);

const releaseAsset = await fetchReleaseAssetMetadataFromTag(
Expand All @@ -70,6 +73,7 @@ async function installGitHubReleaseBinary(
targetRelease.binaryName,
releaseTag,
targetTriple,
targetDuple,
);

const destinationBasename = unwrapOrDefault(
Expand Down
Loading