diff options
-rw-r--r-- | editors/code/.eslintrc.js | 3 | ||||
-rw-r--r-- | editors/code/src/installation/fetch_artifact_release_info.ts | 58 | ||||
-rw-r--r-- | editors/code/src/installation/server.ts | 2 |
3 files changed, 42 insertions, 21 deletions
diff --git a/editors/code/.eslintrc.js b/editors/code/.eslintrc.js index 16f18ab2c..c6bf410f4 100644 --- a/editors/code/.eslintrc.js +++ b/editors/code/.eslintrc.js | |||
@@ -32,6 +32,7 @@ module.exports = { | |||
32 | "@typescript-eslint/semi": [ | 32 | "@typescript-eslint/semi": [ |
33 | "error", | 33 | "error", |
34 | "always" | 34 | "always" |
35 | ] | 35 | ], |
36 | "@typescript-eslint/no-unnecessary-type-assertion": "error" | ||
36 | } | 37 | } |
37 | }; | 38 | }; |
diff --git a/editors/code/src/installation/fetch_artifact_release_info.ts b/editors/code/src/installation/fetch_artifact_release_info.ts index 1b6fc8d48..b1b5a3485 100644 --- a/editors/code/src/installation/fetch_artifact_release_info.ts +++ b/editors/code/src/installation/fetch_artifact_release_info.ts | |||
@@ -4,41 +4,61 @@ import { log } from "../util"; | |||
4 | 4 | ||
5 | const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; | 5 | const GITHUB_API_ENDPOINT_URL = "https://api.github.com"; |
6 | 6 | ||
7 | |||
8 | /** | 7 | /** |
9 | * Fetches the release with `releaseTag` (or just latest release when not specified) | 8 | * Fetches the release with `releaseTag` from GitHub `repo` and |
10 | * from GitHub `repo` and returns metadata about `artifactFileName` shipped with | 9 | * returns metadata about `artifactFileName` shipped with |
11 | * this release or `null` if no such artifact was published. | 10 | * this release. |
11 | * | ||
12 | * @throws Error upon network failure or if no such repository, release, or artifact exists. | ||
12 | */ | 13 | */ |
13 | export async function fetchArtifactReleaseInfo( | 14 | export async function fetchArtifactReleaseInfo( |
14 | repo: GithubRepo, artifactFileName: string, releaseTag?: string | 15 | repo: GithubRepo, |
15 | ): Promise<null | ArtifactReleaseInfo> { | 16 | artifactFileName: string, |
17 | releaseTag: string | ||
18 | ): Promise<ArtifactReleaseInfo> { | ||
16 | 19 | ||
17 | const repoOwner = encodeURIComponent(repo.owner); | 20 | const repoOwner = encodeURIComponent(repo.owner); |
18 | const repoName = encodeURIComponent(repo.name); | 21 | const repoName = encodeURIComponent(repo.name); |
19 | 22 | ||
20 | const apiEndpointPath = releaseTag | 23 | const apiEndpointPath = `/repos/${repoOwner}/${repoName}/releases/tags/${releaseTag}`; |
21 | ? `/repos/${repoOwner}/${repoName}/releases/tags/${releaseTag}` | ||
22 | : `/repos/${repoOwner}/${repoName}/releases/latest`; | ||
23 | 24 | ||
24 | const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; | 25 | const requestUrl = GITHUB_API_ENDPOINT_URL + apiEndpointPath; |
25 | 26 | ||
26 | // We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`) | ||
27 | |||
28 | log.debug("Issuing request for released artifacts metadata to", requestUrl); | 27 | log.debug("Issuing request for released artifacts metadata to", requestUrl); |
29 | 28 | ||
30 | // FIXME: handle non-ok response | 29 | const response = await fetch(requestUrl, { headers: { Accept: "application/vnd.github.v3+json" } }); |
31 | const response: GithubRelease = await fetch(requestUrl, { | ||
32 | headers: { Accept: "application/vnd.github.v3+json" } | ||
33 | }) | ||
34 | .then(res => res.json()); | ||
35 | 30 | ||
36 | const artifact = response.assets.find(artifact => artifact.name === artifactFileName); | 31 | if (!response.ok) { |
32 | log.error("Error fetching artifact release info", { | ||
33 | requestUrl, | ||
34 | releaseTag, | ||
35 | artifactFileName, | ||
36 | response: { | ||
37 | headers: response.headers, | ||
38 | status: response.status, | ||
39 | body: await response.text(), | ||
40 | } | ||
41 | }); | ||
42 | |||
43 | throw new Error( | ||
44 | `Got response ${response.status} when trying to fetch ` + | ||
45 | `"${artifactFileName}" artifact release info for ${releaseTag} release` | ||
46 | ); | ||
47 | } | ||
37 | 48 | ||
38 | if (!artifact) return null; | 49 | // We skip runtime type checks for simplicity (here we cast from `any` to `GithubRelease`) |
50 | const release: GithubRelease = await response.json(); | ||
51 | |||
52 | const artifact = release.assets.find(artifact => artifact.name === artifactFileName); | ||
53 | |||
54 | if (!artifact) { | ||
55 | throw new Error( | ||
56 | `Artifact ${artifactFileName} was not found in ${release.name} release!` | ||
57 | ); | ||
58 | } | ||
39 | 59 | ||
40 | return { | 60 | return { |
41 | releaseName: response.name, | 61 | releaseName: release.name, |
42 | downloadUrl: artifact.browser_download_url | 62 | downloadUrl: artifact.browser_download_url |
43 | }; | 63 | }; |
44 | 64 | ||
diff --git a/editors/code/src/installation/server.ts b/editors/code/src/installation/server.ts index 9de257dd5..cb5e56844 100644 --- a/editors/code/src/installation/server.ts +++ b/editors/code/src/installation/server.ts | |||
@@ -63,7 +63,7 @@ export async function ensureServerBinary(source: null | BinarySource): Promise<n | |||
63 | 63 | ||
64 | async function downloadServer(source: BinarySource.GithubRelease): Promise<boolean> { | 64 | async function downloadServer(source: BinarySource.GithubRelease): Promise<boolean> { |
65 | try { | 65 | try { |
66 | const releaseInfo = (await fetchArtifactReleaseInfo(source.repo, source.file, source.version))!; | 66 | const releaseInfo = await fetchArtifactReleaseInfo(source.repo, source.file, source.version); |
67 | 67 | ||
68 | await downloadArtifact(releaseInfo, source.file, source.dir, "language server"); | 68 | await downloadArtifact(releaseInfo, source.file, source.dir, "language server"); |
69 | await setServerVersion(source.storage, releaseInfo.releaseName); | 69 | await setServerVersion(source.storage, releaseInfo.releaseName); |