Merge pull request #1405 from balena-io/1359-update-release-descriptions

Deploy scripts: edit GitHub release descriptions given semver ranges
This commit is contained in:
Paulo Castro 2019-08-30 18:57:33 +01:00 committed by GitHub
commit 8478b95e45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 434 additions and 8 deletions

View File

@ -16,7 +16,7 @@
*/
import * as Bluebird from 'bluebird';
import * as _ from 'lodash';
import * as publishRelease from 'publish-release';
import * as semver from 'semver';
import { finalReleaseAssets, version } from './build-bin';
@ -28,6 +28,7 @@ const { GITHUB_TOKEN } = process.env;
*/
export async function createGitHubRelease() {
console.log(`Publishing release ${version} to GitHub`);
const publishRelease = await import('publish-release');
const ghRelease = await Bluebird.fromCallback(
publishRelease.bind(null, {
token: GITHUB_TOKEN || '',
@ -57,3 +58,201 @@ export async function release() {
process.exit(1);
}
}
let cachedOctokit: any;
/** Return a cached Octokit instance, creating a new one as needed. */
function getOctokit(): any {
if (cachedOctokit) {
return cachedOctokit;
}
const Octokit = require('@octokit/rest').plugin(
require('@octokit/plugin-throttling'),
);
return (cachedOctokit = new Octokit({
auth: GITHUB_TOKEN,
throttle: {
onRateLimit: (retryAfter: number, options: any) => {
console.warn(
`Request quota exhausted for request ${options.method} ${
options.url
}`,
);
// retries 3 times
if (options.request.retryCount < 3) {
console.log(`Retrying after ${retryAfter} seconds!`);
return true;
}
},
onAbuseLimit: (_retryAfter: number, options: any) => {
// does not retry, only logs a warning
console.warn(
`Abuse detected for request ${options.method} ${options.url}`,
);
},
},
}));
}
/**
* Extract pagination information (current page, total pages, ordinal number)
* from the 'link' response header (example below), using the parse-link-header
* npm package:
* "link": "<https://api.github.com/repositories/187370853/releases?per_page=2&page=2>; rel=\"next\",
* <https://api.github.com/repositories/187370853/releases?per_page=2&page=3>; rel=\"last\""
*
* @param response Octokit response object (including response.headers.link)
* @param perPageDefault Default per_page pagination value if missing in URL
* @return Object where 'page' is the current page number (1-based),
* 'pages' is the total number of pages, and 'ordinal' is the ordinal number
* (3rd, 4th, 5th...) of the first item in the current page.
*/
function getPageNumbers(
response: any,
perPageDefault: number,
): { page: number; pages: number; ordinal: number } {
const res = { page: 1, pages: 1, ordinal: 1 };
if (!response.headers.link) {
return res;
}
const parse = require('parse-link-header');
const parsed = parse(response.headers.link);
let perPage = perPageDefault;
if (parsed.next) {
if (parsed.next.per_page) {
perPage = parseInt(parsed.next.per_page, 10);
}
res.page = parseInt(parsed.next.page, 10) - 1;
res.pages = parseInt(parsed.last.page, 10);
} else {
if (parsed.prev.per_page) {
perPage = parseInt(parsed.prev.per_page, 10);
}
res.page = res.pages = parseInt(parsed.prev.page, 10) + 1;
}
res.ordinal = (res.page - 1) * perPage + 1;
return res;
}
/**
* Iterate over every GitHub release in the given owner/repo, check whether
* its tag_name matches against the affectedVersions semver spec, and if so
* replace its release description (body) with the given newDescription value.
* @param owner GitHub repo owner, e.g. 'balena-io' or 'pdcastro'
* @param repo GitHub repo, e.g. 'balena-cli'
* @param affectedVersions Semver spec, e.g. '2.6.1 - 7.10.9 || 8.0.0'
* @param newDescription New release description (body)
* @param editID Short string present in newDescription, e.g. '[AA101]', that
* can be searched to determine whether that release has already been updated.
*/
async function updateGitHubReleaseDescriptions(
owner: string,
repo: string,
affectedVersions: string,
newDescription: string,
editID: string,
) {
const perPage = 30;
const octokit = getOctokit();
const options = await octokit.repos.listReleases.endpoint.merge({
owner,
repo,
per_page: perPage,
});
let errCount = 0;
for await (const response of octokit.paginate.iterator(options)) {
const { page: thisPage, pages: totalPages, ordinal } = getPageNumbers(
response,
perPage,
);
let i = 0;
for (const cliRelease of response.data) {
const prefix = `[#${ordinal + i++} pg ${thisPage}/${totalPages}]`;
if (!cliRelease.id) {
console.error(
`${prefix} Error: missing release ID (errCount=${++errCount})`,
);
continue;
}
const skipMsg = `${prefix} skipping release "${cliRelease.tag_name}" (${
cliRelease.id
})`;
if (cliRelease.draft === true) {
console.info(`${skipMsg}: draft release`);
continue;
} else if (cliRelease.body && cliRelease.body.includes(editID)) {
console.info(`${skipMsg}: already updated`);
continue;
} else if (!semver.satisfies(cliRelease.tag_name, affectedVersions)) {
console.info(`${skipMsg}: outside version range`);
continue;
} else {
const updatedRelease = {
owner,
repo,
release_id: cliRelease.id,
body: newDescription,
};
let oldBodyPreview = cliRelease.body;
if (oldBodyPreview) {
oldBodyPreview = oldBodyPreview.replace(/\s+/g, ' ').trim();
if (oldBodyPreview.length > 12) {
oldBodyPreview = oldBodyPreview.substring(0, 9) + '...';
}
}
console.info(
`${prefix} updating release "${cliRelease.tag_name}" (${
cliRelease.id
}) old body="${oldBodyPreview}"`,
);
try {
await octokit.repos.updateRelease(updatedRelease);
} catch (err) {
console.error(
`${skipMsg}: Error: ${err.message} (count=${++errCount})`,
);
continue;
}
}
}
}
}
/**
* Add a warning description to CLI releases affected by a mixpanel tracking
* security issue (#1359). This function can be executed "manually" with the
* following command line:
*
* npx ts-node --type-check -P automation/tsconfig.json automation/run.ts fix1359
*/
export async function updateDescriptionOfReleasesAffectedByIssue1359() {
// Run only on Linux/Node10, instead of all platform/Node combinations.
// (It could have been any other platform, as long as it only runs once.)
if (process.platform !== 'linux' || semver.major(process.version) !== 10) {
return;
}
const owner = 'balena-io';
const repo = 'balena-cli';
const affectedVersions =
'2.6.1 - 7.10.9 || 8.0.0 - 8.1.0 || 9.0.0 - 9.15.6 || 10.0.0 - 10.17.5 || 11.0.0 - 11.7.2';
const editID = '[AA100]';
let newDescription = `
Please note: the "login" command in this release is affected by a
security issue fixed in versions
[7.10.10](https://github.com/balena-io/balena-cli/releases/tag/v7.10.10),
[8.1.1](https://github.com/balena-io/balena-cli/releases/tag/v8.1.1),
[9.15.7](https://github.com/balena-io/balena-cli/releases/tag/v9.15.7),
[10.17.6](https://github.com/balena-io/balena-cli/releases/tag/v10.17.6),
[11.7.3](https://github.com/balena-io/balena-cli/releases/tag/v11.7.3)
and later. If you need to use this version, avoid passing your password,
keys or tokens as command-line arguments. ${editID}`;
// remove line breaks and collapse white space
newDescription = newDescription.replace(/\s+/g, ' ').trim();
await updateGitHubReleaseDescriptions(
owner,
repo,
affectedVersions,
newDescription,
editID,
);
}

View File

@ -24,7 +24,16 @@ import {
ROOT,
runUnderMsys,
} from './build-bin';
import { release } from './deploy-bin';
import {
release,
updateDescriptionOfReleasesAffectedByIssue1359,
} from './deploy-bin';
function exitWithError(error: Error | string): never {
console.error(`Error: ${error}`);
process.exit(1);
throw error; // to please the Typescript compiler
}
/**
* Trivial command-line parser. Check whether the command-line argument is one
@ -43,17 +52,17 @@ export async function run(args?: string[]) {
console.log(`automation/run.ts process.argv=[${process.argv}]\n`);
console.log(`automation/run.ts args=[${args}]`);
if (_.isEmpty(args)) {
console.error('Error: missing args');
process.exit(1);
return exitWithError('missing command-line arguments');
}
const commands: { [cmd: string]: () => void } = {
'build:installer': buildOclifInstaller,
'build:standalone': buildStandaloneZip,
fix1359: updateDescriptionOfReleasesAffectedByIssue1359,
release,
};
for (const arg of args) {
if (!commands.hasOwnProperty(arg)) {
throw new Error(`Error: unknown build target: ${arg}`);
return exitWithError(`command unknown: ${arg}`);
}
}
@ -98,8 +107,7 @@ export async function run(args?: string[]) {
const cmdFunc = commands[arg];
await cmdFunc();
} catch (err) {
console.log(`Error running command "${arg}": ${err}`);
process.exit(1);
return exitWithError(`"${arg}": ${err}`);
}
}
}

View File

@ -4,7 +4,7 @@
"target": "es2017",
"strict": true,
"strictPropertyInitialization": false,
"noUnusedLocals": true,
"noUnusedLocals": false,
"noUnusedParameters": true,
"preserveConstEnums": true,
"removeComments": true,

216
npm-shrinkwrap.json generated
View File

@ -301,6 +301,113 @@
"resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-1.0.4.tgz",
"integrity": "sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw=="
},
"@octokit/endpoint": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.3.2.tgz",
"integrity": "sha512-gRjteEM9I6f4D8vtwU2iGUTn9RX/AJ0SVXiqBUEuYEWVGGAVjSXdT0oNmghH5lvQNWs8mwt6ZaultuG6yXivNw==",
"dev": true,
"requires": {
"deepmerge": "4.0.0",
"is-plain-object": "^3.0.0",
"universal-user-agent": "^3.0.0",
"url-template": "^2.0.8"
},
"dependencies": {
"is-plain-object": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
"integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
"dev": true,
"requires": {
"isobject": "^4.0.0"
}
},
"isobject": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
"integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==",
"dev": true
}
}
},
"@octokit/plugin-throttling": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-2.6.0.tgz",
"integrity": "sha512-E0xQrcD36sVEeBhut6j9nWX38vm/1LKMRSUqjvJ/mqGLXfHr4jYMsrR3I/nT2QC0eJL1/SKMt7zxOt7pZiFhDA==",
"dev": true,
"requires": {
"bottleneck": "^2.15.3"
}
},
"@octokit/request": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.0.2.tgz",
"integrity": "sha512-z1BQr43g4kOL4ZrIVBMHwi68Yg9VbkRUyuAgqCp1rU3vbYa69+2gIld/+gHclw15bJWQnhqqyEb7h5a5EqgZ0A==",
"dev": true,
"requires": {
"@octokit/endpoint": "^5.1.0",
"@octokit/request-error": "^1.0.1",
"deprecation": "^2.0.0",
"is-plain-object": "^3.0.0",
"node-fetch": "^2.3.0",
"once": "^1.4.0",
"universal-user-agent": "^3.0.0"
},
"dependencies": {
"is-plain-object": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
"integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
"dev": true,
"requires": {
"isobject": "^4.0.0"
}
},
"isobject": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
"integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==",
"dev": true
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
"dev": true
}
}
},
"@octokit/request-error": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.0.4.tgz",
"integrity": "sha512-L4JaJDXn8SGT+5G0uX79rZLv0MNJmfGa4vb4vy1NnpjSnWDLJRy6m90udGwvMmavwsStgbv2QNkPzzTCMmL+ig==",
"dev": true,
"requires": {
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/rest": {
"version": "16.28.7",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.28.7.tgz",
"integrity": "sha512-cznFSLEhh22XD3XeqJw51OLSfyL2fcFKUO+v2Ep9MTAFfFLS1cK1Zwd1yEgQJmJoDnj4/vv3+fGGZweG+xsbIA==",
"dev": true,
"requires": {
"@octokit/request": "^5.0.0",
"@octokit/request-error": "^1.0.2",
"atob-lite": "^2.0.0",
"before-after-hook": "^2.0.0",
"btoa-lite": "^1.0.0",
"deprecation": "^2.0.0",
"lodash.get": "^4.4.2",
"lodash.set": "^4.3.2",
"lodash.uniq": "^4.5.0",
"octokit-pagination-methods": "^1.1.0",
"once": "^1.4.0",
"universal-user-agent": "^3.0.0",
"url-template": "^2.0.8"
}
},
"@resin.io/types-hidepath": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@resin.io/types-hidepath/-/types-hidepath-1.0.1.tgz",
@ -1178,6 +1285,12 @@
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
},
"atob-lite": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz",
"integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=",
"dev": true
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@ -2077,6 +2190,12 @@
"integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=",
"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==",
"dev": true
},
"big-integer": {
"version": "1.6.44",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.44.tgz",
@ -2293,6 +2412,12 @@
"multicast-dns-service-types": "^1.1.0"
}
},
"bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==",
"dev": true
},
"boxen": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
@ -2356,6 +2481,12 @@
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
"btoa-lite": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
"integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=",
"dev": true
},
"buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
@ -3433,6 +3564,12 @@
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
"deepmerge": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.0.0.tgz",
"integrity": "sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww==",
"dev": true
},
"default-compare": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
@ -3754,6 +3891,12 @@
"integrity": "sha512-b5dDNQYdy2vW9WXUD8+RQlfoxvqztLLhDE+T7Gd37I5E8My7nJkKu6FmhdDeRWJ8B+yjZKuwjCta8pgi8kgSqA==",
"dev": true
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
"dev": true
},
"deps-regex": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.1.4.tgz",
@ -7881,6 +8024,12 @@
"lodash._root": "^3.0.0"
}
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
"dev": true
},
"lodash.isarguments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
@ -7906,6 +8055,12 @@
"resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
"integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU="
},
"lodash.set": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
"integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=",
"dev": true
},
"lodash.template": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz",
@ -7923,6 +8078,12 @@
"lodash._reinterpolate": "~3.0.0"
}
},
"lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
"dev": true
},
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
@ -8008,6 +8169,12 @@
"integrity": "sha1-qsz7nv62fdbpRkm5HMErNtAtLPE=",
"optional": true
},
"macos-release": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
"integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==",
"dev": true
},
"make-dir": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
@ -12761,6 +12928,12 @@
"yosay": "^2.0.2"
}
},
"octokit-pagination-methods": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz",
"integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==",
"dev": true
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@ -12886,6 +13059,16 @@
"lcid": "^1.0.0"
}
},
"os-name": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz",
"integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==",
"dev": true,
"requires": {
"macos-release": "^2.2.0",
"windows-release": "^3.1.0"
}
},
"os-shim": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz",
@ -13027,6 +13210,15 @@
"json-parse-better-errors": "^1.0.1"
}
},
"parse-link-header": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-1.0.1.tgz",
"integrity": "sha1-vt/g0hGK64S+deewJUGeyKYRQKc=",
"dev": true,
"requires": {
"xtend": "~4.0.1"
}
},
"parse-node-version": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
@ -16985,6 +17177,15 @@
"moment": "^2.14.1"
}
},
"universal-user-agent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-3.0.0.tgz",
"integrity": "sha512-T3siHThqoj5X0benA5H0qcDnrKGXzU8TKoX15x/tQHw1hQBvIEBHjxQ2klizYsqBOO/Q+WuxoQUihadeeqDnoA==",
"dev": true,
"requires": {
"os-name": "^3.0.0"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
@ -17190,6 +17391,12 @@
"prepend-http": "^1.0.1"
}
},
"url-template": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
"integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=",
"dev": true
},
"url-to-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
@ -17542,6 +17749,15 @@
}
}
},
"windows-release": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz",
"integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==",
"dev": true,
"requires": {
"execa": "^1.0.0"
}
},
"winusb-driver-generator": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/winusb-driver-generator/-/winusb-driver-generator-1.2.4.tgz",

View File

@ -80,6 +80,8 @@
"@oclif/config": "^1.12.12",
"@oclif/dev-cli": "1.22.0",
"@oclif/parser": "^3.7.3",
"@octokit/plugin-throttling": "^2.6.0",
"@octokit/rest": "^16.28.7",
"@types/archiver": "2.1.2",
"@types/bluebird": "3.5.21",
"@types/chai": "^4.1.7",
@ -120,6 +122,7 @@
"gulp-shell": "^0.5.2",
"mocha": "^6.2.0",
"nock": "^10.0.6",
"parse-link-header": "~1.0.1",
"pkg": "^4.4.0",
"prettier": "1.17.0",
"publish-release": "^1.6.0",