1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
import fetch from "node-fetch";
import { GithubRepo, ArtifactReleaseInfo } from "./interfaces";
import { log } from "../util";
const GITHUB_API_ENDPOINT_URL = "https://api.github.com";
/**
* Fetches the release with `releaseTag` from GitHub `repo` and
* returns metadata about `artifactFileName` shipped with
* this release.
*
* @throws Error upon network failure or if no such repository, release, or artifact exists.
*/
export async function fetchArtifactReleaseInfo(
repo: GithubRepo,
artifactFileName: string,
releaseTag: string
): Promise<ArtifactReleaseInfo> {
const repoOwner = encodeURIComponent(repo.owner);
const repoName = encodeURIComponent(repo.name);
const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/tags/${releaseTag}`;
const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath;
log.debug("Issuing request for released artifacts metadata to", requestUrl);
const response = await fetch(requestUrl, { headers: { Accept: "application/vnd.github.v3+json" } });
if (!response.ok) {
log.error("Error fetching artifact release info", {
requestUrl,
releaseTag,
artifactFileName,
response: {
headers: response.headers,
status: response.status,
body: await response.text(),
}
});
throw new Error(
`Got response ${response.status} when trying to fetch ` +
`"${artifactFileName}" artifact release info for ${releaseTag} release`
);
}
// We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`)
const release: GithubRelease = await response.json();
const artifact = release.assets.find(artifact => artifact.name === artifactFileName);
if (!artifact) {
throw new Error(
`Artifact ${artifactFileName} was not found in ${release.name} release!`
);
}
return {
releaseName: release.name,
downloadUrl: artifact.browser_download_url
};
// We omit declaration of tremendous amount of fields that we are not using here
interface GithubRelease {
name: string;
assets: Array<{
name: string;
// eslint-disable-next-line camelcase
browser_download_url: string;
}>;
}
}
|