From dea6ed51a55dafa3750b811ebbdcce63e7e8c8be Mon Sep 17 00:00:00 2001 From: rhysd Date: Wed, 9 Sep 2020 00:31:18 +0900 Subject: [PATCH 1/5] fetch latest Neovim version if 'stable' release is unavailable --- .gitignore | 1 + action.yml | 11 +++- package-lock.json | 142 +++++++++++++++++++++++++++++++++++++++-- package.json | 1 + src/config.ts | 2 + src/install_linux.ts | 18 +++++- src/install_windows.ts | 18 +++++- src/neovim.ts | 15 +++++ 8 files changed, 197 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 443dde58..4ac455d4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /test/*.js /scripts/*.js *.js.map +/env.sh diff --git a/action.yml b/action.yml index 9f91367f..7a0a5b1a 100644 --- a/action.yml +++ b/action.yml @@ -14,13 +14,20 @@ inputs: required: false default: 'stable' neovim: - description: 'Setting to true will install Neovim.' + description: > + Setting to true will install Neovim. required: false default: false + token: + description: > + Personal access token. It is used for calling GitHub API. The API call happens when Neovim + asset is not found and needs to fallback. + default: ${{ github.token }} outputs: executable: - description: 'Absolute file path to the installed executable' + description: > + Absolute file path to the installed executable. runs: using: 'node12' diff --git a/package-lock.json b/package-lock.json index cd1e4281..1db98a25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,25 @@ "@actions/io": "^1.0.1" } }, + "@actions/github": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-4.0.0.tgz", + "integrity": "sha512-Ej/Y2E+VV6sR9X7pWL5F3VgEWrABaT292DRqRU6R4hnQjPtC/zD3nagxVdXWiRQvYDh8kHXo7IDmG42eJ/dOMA==", + "requires": { + "@actions/http-client": "^1.0.8", + "@octokit/core": "^3.0.0", + "@octokit/plugin-paginate-rest": "^2.2.3", + "@octokit/plugin-rest-endpoint-methods": "^4.0.0" + } + }, + "@actions/http-client": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", + "integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", + "requires": { + "tunnel": "0.0.6" + } + }, "@actions/io": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz", @@ -383,6 +402,97 @@ "fastq": "^1.6.0" } }, + "@octokit/auth-token": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.2.tgz", + "integrity": "sha512-jE/lE/IKIz2v1+/P0u4fJqv0kYwXOTujKemJMFr6FeopsxlIK3+wKDCJGnysg81XID5TgZQbIfuJ5J0lnTiuyQ==", + "requires": { + "@octokit/types": "^5.0.0" + } + }, + "@octokit/core": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.1.2.tgz", + "integrity": "sha512-AInOFULmwOa7+NFi9F8DlDkm5qtZVmDQayi7TUgChE3yeIGPq0Y+6cAEXPexQ3Ea+uZy66hKEazR7DJyU+4wfw==", + "requires": { + "@octokit/auth-token": "^2.4.0", + "@octokit/graphql": "^4.3.1", + "@octokit/request": "^5.4.0", + "@octokit/types": "^5.0.0", + "before-after-hook": "^2.1.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.5.tgz", + "integrity": "sha512-70K5u6zd45ItOny6aHQAsea8HHQjlQq85yqOMe+Aj8dkhN2qSJ9T+Q3YjUjEYfPRBcuUWNgMn62DQnP/4LAIiQ==", + "requires": { + "@octokit/types": "^5.0.0", + "is-plain-object": "^4.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.4.tgz", + "integrity": "sha512-ITpZ+dQc0cXAW1FmDkHJJM+8Lb6anUnin0VB5hLBilnYVdLC0ICFU/KIvT7OXfW9S81DE3U4Vx2EypDG1OYaPA==", + "requires": { + "@octokit/request": "^5.3.0", + "@octokit/types": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/plugin-paginate-rest": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.3.2.tgz", + "integrity": "sha512-PjHbMhKryxClCrmfvRpGaKCTxUcHIf2zirWRV9SMGf0EmxD/rFew/abSqbMiLl9uQgRZvqtTyCRMGMlUv1ZsBg==", + "requires": { + "@octokit/types": "^5.3.0" + } + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.1.4.tgz", + "integrity": "sha512-Y2tVpSa7HjV3DGIQrQOJcReJ2JtcN9FaGr9jDa332Flro923/h3/Iu9e7Y4GilnzfLclHEh5iCQoCkHm7tWOcg==", + "requires": { + "@octokit/types": "^5.4.1", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "5.4.7", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.7.tgz", + "integrity": "sha512-FN22xUDP0i0uF38YMbOfx6TotpcENP5W8yJM1e/LieGXn6IoRxDMnBf7tx5RKSW4xuUZ/1P04NFZy5iY3Rax1A==", + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.0.0", + "@octokit/types": "^5.0.0", + "deprecation": "^2.0.0", + "is-plain-object": "^4.0.0", + "node-fetch": "^2.3.0", + "once": "^1.4.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.2.tgz", + "integrity": "sha512-2BrmnvVSV1MXQvEkrb9zwzP0wXFNbPJij922kYBTLIlIafukrGOb+ABBT2+c6wZiuyWDH1K1zmjGQ0toN/wMWw==", + "requires": { + "@octokit/types": "^5.0.1", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.4.1.tgz", + "integrity": "sha512-OlMlSySBJoJ6uozkr/i03nO5dlYQyE05vmQNZhAh9MyO4DPBP88QlwsDVLmVjIMFssvIZB6WO0ctIGMRG+xsJQ==", + "requires": { + "@types/node": ">= 8" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -413,8 +523,7 @@ "@types/node": { "version": "14.6.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.4.tgz", - "integrity": "sha512-Wk7nG1JSaMfMpoMJDKUsWYugliB2Vy55pdjLpmLixeyMi7HizW2I/9QoxsPCkXl3dO+ZOVqPumKaDUv5zJu2uQ==", - "dev": true + "integrity": "sha512-Wk7nG1JSaMfMpoMJDKUsWYugliB2Vy55pdjLpmLixeyMi7HizW2I/9QoxsPCkXl3dO+ZOVqPumKaDUv5zJu2uQ==" }, "@types/node-fetch": { "version": "2.5.7", @@ -664,6 +773,11 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "before-after-hook": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz", + "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==" + }, "binary-extensions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", @@ -916,6 +1030,11 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -1846,6 +1965,11 @@ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, + "is-plain-object": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-4.1.1.tgz", + "integrity": "sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==" + }, "is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -2717,7 +2841,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -3352,6 +3475,11 @@ "tslib": "^1.8.1" } }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3382,6 +3510,11 @@ "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", "dev": true }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, "uri-js": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", @@ -3513,8 +3646,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", diff --git a/package.json b/package.json index 701347df..64871daf 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "dependencies": { "@actions/core": "^1.2.5", "@actions/exec": "^1.0.4", + "@actions/github": "^4.0.0", "@actions/io": "^1.0.2", "node-fetch": "^2.6.1" }, diff --git a/src/config.ts b/src/config.ts index 29c10524..58c772cb 100644 --- a/src/config.ts +++ b/src/config.ts @@ -6,6 +6,7 @@ export interface Config { readonly version: string; readonly neovim: boolean; readonly os: Os; + readonly token: string | null; } function getBoolean(input: string, def: boolean): boolean { @@ -67,5 +68,6 @@ export function loadConfigFromInputs(): Config { version: getVersion(neovim), neovim, os: getOs(), + token: getInput('token') ?? null, }; } diff --git a/src/install_linux.ts b/src/install_linux.ts index e8f2d40a..cf3ceaf8 100644 --- a/src/install_linux.ts +++ b/src/install_linux.ts @@ -4,7 +4,7 @@ import type { Installed } from './install'; import type { Config } from './config'; import { exec } from './shell'; import { buildVim } from './vim'; -import { downloadNeovim } from './neovim'; +import { downloadNeovim, fetchLatestNeovimVersion } from './neovim'; async function installVimStable(): Promise { core.debug('Installing stable Vim on Linux using apt'); @@ -34,11 +34,25 @@ async function installNeovim(ver: string): Promise { }; } +async function installStableNeovim(token: string | null): Promise { + try { + return installNeovim('stable'); + } catch (err) { + if (err.message.includes('Downloading asset failed:') && token !== null) { + core.warning(`Could not download stable asset. Trying fallback: ${err.message}`); + const ver = await fetchLatestNeovimVersion(token); + core.warning(`Fallback to install asset from '${ver}' release`); + return installNeovim(ver); + } + throw err; + } +} + export function install(config: Config): Promise { if (config.neovim) { switch (config.version) { case 'stable': - return installNeovim('stable'); + return installStableNeovim(config.token); case 'nightly': return installNeovim('nightly'); default: diff --git a/src/install_windows.ts b/src/install_windows.ts index 6ae5f36b..4c951d61 100644 --- a/src/install_windows.ts +++ b/src/install_windows.ts @@ -3,7 +3,7 @@ import * as core from '@actions/core'; import type { Installed } from './install'; import type { Config } from './config'; import { installNightlyVimOnWindows, installVimOnWindows } from './vim'; -import { downloadNeovim } from './neovim'; +import { downloadNeovim, fetchLatestNeovimVersion } from './neovim'; async function installVimNightly(): Promise { core.debug('Installing nightly Vim on Windows'); @@ -38,11 +38,25 @@ async function installNeovim(ver: string): Promise { }; } +async function installStableNeovim(token: string | null): Promise { + try { + return installNeovim('stable'); + } catch (err) { + if (err.message.includes('Downloading asset failed:') && token !== null) { + core.warning(`Could not download stable asset. Trying fallback: ${err.message}`); + const ver = await fetchLatestNeovimVersion(token); + core.warning(`Fallback to install asset from '${ver}' release`); + return installNeovim(ver); + } + throw err; + } +} + export function install(config: Config): Promise { if (config.neovim) { switch (config.version) { case 'stable': - return installNeovim('stable'); + return installStableNeovim(config.token); case 'nightly': return installNeovim('nightly'); default: diff --git a/src/neovim.ts b/src/neovim.ts index ee9f92ea..8f275a17 100644 --- a/src/neovim.ts +++ b/src/neovim.ts @@ -7,6 +7,21 @@ import * as io from '@actions/io'; import { makeTmpdir } from './utils'; import type { Os } from './config'; import { exec } from './shell'; +import * as github from '@actions/github'; + +export async function fetchLatestNeovimVersion(token: string): Promise { + const octokit = github.getOctokit(token); + const { data } = await octokit.repos.listReleases({ owner: 'neovim', repo: 'neovim' }); + const re = /^v\d+\.\d+\.\d+$/; + for (const release of data) { + const tagName = release.tag_name; + if (re.test(tagName)) { + core.debug(`Detected the latest stable version '${tagName}'`); + return tagName; + } + } + throw new Error(`No stable version was found in ${data.length} releases`); +} function assetFileName(os: Os) { switch (os) { From 644332a7ef5a545ebe5783365bc38f21a5d3e3f2 Mon Sep 17 00:00:00 2001 From: rhysd Date: Wed, 9 Sep 2020 01:39:21 +0900 Subject: [PATCH 2/5] move fallback logic for downloading Neovim stable asset to neovim.ts --- src/install_linux.ts | 24 +++++++++-------------- src/install_windows.ts | 24 +++++++++-------------- src/neovim.ts | 44 ++++++++++++++++++++++++++++-------------- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/install_linux.ts b/src/install_linux.ts index cf3ceaf8..b915ca51 100644 --- a/src/install_linux.ts +++ b/src/install_linux.ts @@ -4,7 +4,7 @@ import type { Installed } from './install'; import type { Config } from './config'; import { exec } from './shell'; import { buildVim } from './vim'; -import { downloadNeovim, fetchLatestNeovimVersion } from './neovim'; +import { downloadNeovim, downloadStableNeovim } from './neovim'; async function installVimStable(): Promise { core.debug('Installing stable Vim on Linux using apt'); @@ -25,27 +25,21 @@ async function installVim(ver: string | null): Promise { }; } -async function installNeovim(ver: string): Promise { - core.debug(`Installing Neovim version '${ver}' on Linux`); - const nvimDir = await downloadNeovim(ver, 'linux'); +function neovimInstalled(nvimDir: string): Installed { return { executable: 'nvim', binDir: path.join(nvimDir, 'bin'), }; } +async function installNeovim(ver: string): Promise { + core.debug(`Installing Neovim version '${ver}' on Linux`); + return neovimInstalled(await downloadNeovim(ver, 'linux')); +} + async function installStableNeovim(token: string | null): Promise { - try { - return installNeovim('stable'); - } catch (err) { - if (err.message.includes('Downloading asset failed:') && token !== null) { - core.warning(`Could not download stable asset. Trying fallback: ${err.message}`); - const ver = await fetchLatestNeovimVersion(token); - core.warning(`Fallback to install asset from '${ver}' release`); - return installNeovim(ver); - } - throw err; - } + core.debug(`Installing Neovim version 'stable' on Linux`); + return neovimInstalled(await downloadStableNeovim('linux', token)); } export function install(config: Config): Promise { diff --git a/src/install_windows.ts b/src/install_windows.ts index 4c951d61..317287ee 100644 --- a/src/install_windows.ts +++ b/src/install_windows.ts @@ -3,7 +3,7 @@ import * as core from '@actions/core'; import type { Installed } from './install'; import type { Config } from './config'; import { installNightlyVimOnWindows, installVimOnWindows } from './vim'; -import { downloadNeovim, fetchLatestNeovimVersion } from './neovim'; +import { downloadNeovim, downloadStableNeovim } from './neovim'; async function installVimNightly(): Promise { core.debug('Installing nightly Vim on Windows'); @@ -29,27 +29,21 @@ async function installVim(ver: string): Promise { }; } -async function installNeovim(ver: string): Promise { - core.debug(`Installing Neovim version '${ver}' on Windows`); - const nvimDir = await downloadNeovim(ver, 'windows'); +function neovimInstalled(nvimDir: string): Installed { return { executable: 'nvim.exe', binDir: path.join(nvimDir, 'bin'), }; } +async function installNeovim(ver: string): Promise { + core.debug(`Installing Neovim version '${ver}' on Windows`); + return neovimInstalled(await downloadNeovim(ver, 'windows')); +} + async function installStableNeovim(token: string | null): Promise { - try { - return installNeovim('stable'); - } catch (err) { - if (err.message.includes('Downloading asset failed:') && token !== null) { - core.warning(`Could not download stable asset. Trying fallback: ${err.message}`); - const ver = await fetchLatestNeovimVersion(token); - core.warning(`Fallback to install asset from '${ver}' release`); - return installNeovim(ver); - } - throw err; - } + core.debug(`Installing Neovim version 'stable' on Windows`); + return neovimInstalled(await downloadStableNeovim('windows', token)); } export function install(config: Config): Promise { diff --git a/src/neovim.ts b/src/neovim.ts index 8f275a17..ba220a2a 100644 --- a/src/neovim.ts +++ b/src/neovim.ts @@ -9,20 +9,6 @@ import type { Os } from './config'; import { exec } from './shell'; import * as github from '@actions/github'; -export async function fetchLatestNeovimVersion(token: string): Promise { - const octokit = github.getOctokit(token); - const { data } = await octokit.repos.listReleases({ owner: 'neovim', repo: 'neovim' }); - const re = /^v\d+\.\d+\.\d+$/; - for (const release of data) { - const tagName = release.tag_name; - if (re.test(tagName)) { - core.debug(`Detected the latest stable version '${tagName}'`); - return tagName; - } - } - throw new Error(`No stable version was found in ${data.length} releases`); -} - function assetFileName(os: Os) { switch (os) { case 'macos': @@ -94,3 +80,33 @@ export async function downloadNeovim(version: string, os: Os): Promise { throw new Error(msg); } } + +async function fetchLatestVersion(token: string): Promise { + const octokit = github.getOctokit(token); + const { data } = await octokit.repos.listReleases({ owner: 'neovim', repo: 'neovim' }); + const re = /^v\d+\.\d+\.\d+$/; + for (const release of data) { + const tagName = release.tag_name; + if (re.test(tagName)) { + core.debug(`Detected the latest stable version '${tagName}'`); + return tagName; + } + } + throw new Error(`No stable version was found in ${data.length} releases`); +} + +// Download stable asset from 'stable' release. When the asset is not found, get the latest version +// using GitHub API and retry downloading an asset with the version as fallback (#5). +export async function downloadStableNeovim(os: Os, token: string | null): Promise { + try { + return downloadNeovim('stable', os); + } catch (err) { + if (err.message.includes('Downloading asset failed:') && token !== null) { + core.warning(`Could not download stable asset. Trying fallback: ${err.message}`); + const ver = await fetchLatestVersion(token); + core.warning(`Fallback to install asset from '${ver}' release`); + return downloadNeovim(ver, os); + } + throw err; + } +} From efa86097779ab2ef0d353c3da4c04fe3b480b840 Mon Sep 17 00:00:00 2001 From: rhysd Date: Wed, 9 Sep 2020 02:25:34 +0900 Subject: [PATCH 3/5] add test for checking fallback on downloading stable Neovim asset --- src/neovim.ts | 4 ++-- test/neovim.ts | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/neovim.ts b/src/neovim.ts index ba220a2a..f2da3f67 100644 --- a/src/neovim.ts +++ b/src/neovim.ts @@ -97,9 +97,9 @@ async function fetchLatestVersion(token: string): Promise { // Download stable asset from 'stable' release. When the asset is not found, get the latest version // using GitHub API and retry downloading an asset with the version as fallback (#5). -export async function downloadStableNeovim(os: Os, token: string | null): Promise { +export async function downloadStableNeovim(os: Os, token: string | null = null): Promise { try { - return downloadNeovim('stable', os); + return await downloadNeovim('stable', os); // `await` is necessary to catch excetipn } catch (err) { if (err.message.includes('Downloading asset failed:') && token !== null) { core.warning(`Could not download stable asset. Trying fallback: ${err.message}`); diff --git a/test/neovim.ts b/test/neovim.ts index 15d2a35f..e8f9a66d 100644 --- a/test/neovim.ts +++ b/test/neovim.ts @@ -10,12 +10,15 @@ describe('downloadNeovim()', function () { context('with mocking fetch()', function () { let downloadNeovim: (tag: string, os: string) => Promise; + let downloadStableNeovim: (os: string, token: string | null) => Promise; before(function () { mock('node-fetch', async (url: string) => Promise.resolve(new Response(`dummy response for ${url}`, { status: 404, statusText: 'Not found' })), ); - downloadNeovim = mock.reRequire('../src/neovim').downloadNeovim; + const mod = mock.reRequire('../src/neovim'); + downloadNeovim = mod.downloadNeovim; + downloadStableNeovim = mod.downloadStableNeovim; }); after(function () { @@ -34,5 +37,19 @@ describe('downloadNeovim()', function () { A.ok(msg.includes('Note that some assets are sometimes missing on nightly build'), msg); } }); + + it('fallbacks to the latest version detected from GitHub API', async function () { + const token = process.env.GITHUB_TOKEN ?? null; + if (token === null) { + this.skip(); // GitHub API token is necessary + } + try { + const ret = await downloadStableNeovim('linux', token); + A.ok(false, `Exception was not thrown: ${ret}`); + } catch (err) { + // Matches to version tag like '/v0.4.4/' as part of download URL in error message + A.match(err.message, /\/v\d+\.\d+\.\d+\//); + } + }); }); }); From a7b970bdc7bb50bfa79e19678bde28b86a109d49 Mon Sep 17 00:00:00 2001 From: rhysd Date: Wed, 9 Sep 2020 02:30:21 +0900 Subject: [PATCH 4/5] set GitHub token on running unit tests --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c957e54..fb2bc961 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,7 +68,10 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 - run: npm ci - - run: npm test + - name: Run unit tests + run: npm test + env: + GITHUB_TOKEN: ${{ github.token }} - run: npm run lint - uses: actions/setup-python@v1 - run: pip install yamllint From a63a9f8c2ac689f532107688390b6716abee9e63 Mon Sep 17 00:00:00 2001 From: rhysd Date: Wed, 9 Sep 2020 02:34:07 +0900 Subject: [PATCH 5/5] do not use assert.match because Node v12 does not support it --- test/neovim.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/neovim.ts b/test/neovim.ts index e8f9a66d..f886c676 100644 --- a/test/neovim.ts +++ b/test/neovim.ts @@ -48,7 +48,8 @@ describe('downloadNeovim()', function () { A.ok(false, `Exception was not thrown: ${ret}`); } catch (err) { // Matches to version tag like '/v0.4.4/' as part of download URL in error message - A.match(err.message, /\/v\d+\.\d+\.\d+\//); + // Note: assert.match is not available in Node v12 + A.ok(/\/v\d+\.\d+\.\d+\//.test(err.message), err.message); } }); });