From ab5bd9d69619662111840bd7c559cd60e24e3cdc Mon Sep 17 00:00:00 2001 From: eric sciple Date: Sat, 18 Jan 2020 14:28:37 -0500 Subject: [PATCH] octokit client should follow proxy settings (#314) --- .github/workflows/unit-tests.yml | 2 + packages/github/README.md | 4 +- packages/github/__tests__/github.test.ts | 173 ++++++++++++++++++ packages/github/__tests__/proxy.d.ts | 5 + packages/github/package-lock.json | 142 +++++++++++++- packages/github/package.json | 6 +- packages/github/src/github.ts | 119 +++++++++++- packages/github/tsconfig.json | 1 - .../glob/__tests__/internal-pattern.test.ts | 24 +-- packages/glob/package-lock.json | 5 - packages/glob/src/internal-path-helper.ts | 2 +- packages/glob/src/internal-path.ts | 2 +- packages/glob/src/internal-pattern.ts | 15 +- .../tool-cache/__tests__/tool-cache.test.ts | 2 +- packages/tool-cache/package-lock.json | 32 ++-- packages/tool-cache/package.json | 4 +- packages/tool-cache/src/tool-cache.ts | 2 +- tsconfig.json | 1 + 18 files changed, 473 insertions(+), 68 deletions(-) create mode 100644 packages/github/__tests__/github.test.ts create mode 100644 packages/github/__tests__/proxy.d.ts diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index bbed17d4..b558b4eb 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -41,6 +41,8 @@ jobs: - name: npm test run: npm test + env: + GITHUB_TOKEN: ${{ github.token }} - name: Lint run: npm run lint diff --git a/packages/github/README.md b/packages/github/README.md index 12c5b0b0..bd5f708b 100644 --- a/packages/github/README.md +++ b/packages/github/README.md @@ -4,7 +4,7 @@ ## Usage -Returns an Octokit client. See https://octokit.github.io/rest.js for the API. +Returns an authenticated Octokit client that follows the machine [proxy settings](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-self-hosted-runners#using-a-proxy-server-with-self-hosted-runners). See https://octokit.github.io/rest.js for the API. ```js const github = require('@actions/github'); @@ -34,7 +34,7 @@ async function run() { run(); ``` -You can pass client options (except `auth`, which is handled by the token argument), as specified by [Octokit](https://octokit.github.io/rest.js/), as a second argument to the `GitHub` constructor. +You can pass client options, as specified by [Octokit](https://octokit.github.io/rest.js/), as a second argument to the `GitHub` constructor. You can also make GraphQL requests. See https://github.com/octokit/graphql.js for the API. diff --git a/packages/github/__tests__/github.test.ts b/packages/github/__tests__/github.test.ts new file mode 100644 index 00000000..0d530956 --- /dev/null +++ b/packages/github/__tests__/github.test.ts @@ -0,0 +1,173 @@ +import * as http from 'http' +import proxy from 'proxy' +import {GitHub} from '../src/github' + +describe('@actions/github', () => { + const proxyUrl = 'http://127.0.0.1:8080' + const originalProxyUrl = process.env['https_proxy'] + let proxyConnects: string[] + let proxyServer: http.Server + let first = true + + beforeAll(async () => { + // Start proxy server + proxyServer = proxy() as http.Server + await new Promise(resolve => { + const port = Number(proxyUrl.split(':')[2]) + proxyServer.listen(port, () => resolve()) + }) + proxyServer.on('connect', req => { + proxyConnects.push(req.url) + }) + }) + + beforeEach(() => { + delete process.env['https_proxy'] + proxyConnects = [] + }) + + afterAll(async () => { + // Stop proxy server + await new Promise(resolve => { + proxyServer.once('close', () => resolve()) + proxyServer.close() + }) + + if (originalProxyUrl) { + process.env['https_proxy'] = originalProxyUrl + } + }) + + it('basic REST client', async () => { + const token = getToken() + if (!token) { + return + } + + const octokit = new GitHub(token) + const branch = await octokit.repos.getBranch({ + owner: 'actions', + repo: 'toolkit', + branch: 'master' + }) + expect(branch.data.name).toBe('master') + expect(proxyConnects).toHaveLength(0) + }) + + it('basic REST client with custom auth', async () => { + const token = getToken() + if (!token) { + return + } + + // Valid token + let octokit = new GitHub({auth: `token ${token}`}) + const branch = await octokit.repos.getBranch({ + owner: 'actions', + repo: 'toolkit', + branch: 'master' + }) + expect(branch.data.name).toBe('master') + expect(proxyConnects).toHaveLength(0) + + // Invalid token + octokit = new GitHub({auth: `token asdf`}) + let failed = false + try { + await octokit.repos.getBranch({ + owner: 'actions', + repo: 'toolkit', + branch: 'master' + }) + } catch (err) { + failed = true + } + expect(failed).toBeTruthy() + }) + + it('basic REST client with proxy', async () => { + const token = getToken() + if (!token) { + return + } + + process.env['https_proxy'] = proxyUrl + const octokit = new GitHub(token) + const branch = await octokit.repos.getBranch({ + owner: 'actions', + repo: 'toolkit', + branch: 'master' + }) + expect(branch.data.name).toBe('master') + expect(proxyConnects).toEqual(['api.github.com:443']) + }) + + it('basic GraphQL client', async () => { + const token = getToken() + if (!token) { + return + } + + const octokit = new GitHub(token) + const repository = await octokit.graphql( + '{repository(owner:"actions", name:"toolkit"){name}}' + ) + expect(repository).toEqual({repository: {name: 'toolkit'}}) + expect(proxyConnects).toHaveLength(0) + }) + + it('basic GraphQL client with custom auth', async () => { + const token = getToken() + if (!token) { + return + } + + // Valid token + let octokit = new GitHub(token) + const repository = await octokit.graphql( + '{repository(owner:"actions", name:"toolkit"){name}}' + ) + expect(repository).toEqual({repository: {name: 'toolkit'}}) + expect(proxyConnects).toHaveLength(0) + + // Invalid token + octokit = new GitHub({auth: `token asdf`}) + let failed = false + try { + await octokit.graphql( + '{repository(owner:"actions", name:"toolkit"){name}}' + ) + } catch (err) { + failed = true + } + expect(failed).toBeTruthy() + }) + + it('basic GraphQL client with proxy', async () => { + const token = getToken() + if (!token) { + return + } + + process.env['https_proxy'] = proxyUrl + const octokit = new GitHub(token) + const repository = await octokit.graphql( + '{repository(owner:"actions", name:"toolkit"){name}}' + ) + expect(repository).toEqual({repository: {name: 'toolkit'}}) + expect(proxyConnects).toEqual(['api.github.com:443']) + }) + + function getToken(): string { + const token = process.env['GITHUB_TOKEN'] || '' + if (!token && first) { + /* eslint-disable-next-line no-console */ + console.warn( + 'Skipping GitHub tests. Set $GITHUB_TOKEN to run REST client and GraphQL client tests' + ) + first = false + } + + return token + } +}) diff --git a/packages/github/__tests__/proxy.d.ts b/packages/github/__tests__/proxy.d.ts new file mode 100644 index 00000000..9b61127b --- /dev/null +++ b/packages/github/__tests__/proxy.d.ts @@ -0,0 +1,5 @@ +declare module 'proxy' { + import * as http from 'http' + function internal(): http.Server + export = internal +} diff --git a/packages/github/package-lock.json b/packages/github/package-lock.json index c2ac4ab0..983f083d 100644 --- a/packages/github/package-lock.json +++ b/packages/github/package-lock.json @@ -1,9 +1,17 @@ { "name": "@actions/github", - "version": "2.0.1", + "version": "2.0.2", "lockfileVersion": 1, "requires": true, "dependencies": { + "@actions/http-client": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.2.tgz", + "integrity": "sha512-ngdGx7aXM7i9BFT+7e3RWWAEt3bX4tKrdI5w5hf0wYpHz66u5Nw6AFSFXG5wzQyUQbkgeNRnJZyK2zciGqXgrQ==", + "requires": { + "tunnel": "0.0.6" + } + }, "@babel/code-frame": { "version": "7.5.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", @@ -686,6 +694,67 @@ "normalize-path": "^2.1.1" } }, + "args": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/args/-/args-3.0.2.tgz", + "integrity": "sha1-hQu46IHzE5IDpeTLF2QxCStWLC0=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "chalk": "1.1.3", + "minimist": "1.2.0", + "pkginfo": "0.4.0", + "string-similarity": "1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -886,6 +955,12 @@ } } }, + "basic-auth-parser": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/basic-auth-parser/-/basic-auth-parser-0.0.2.tgz", + "integrity": "sha1-zp5xp38jwSee7NJlmypGJEwVbkE=", + "dev": true + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -2401,6 +2476,23 @@ "function-bind": "^1.1.1" } }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -4046,6 +4138,12 @@ "find-up": "^3.0.0" } }, + "pkginfo": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.0.tgz", + "integrity": "sha1-NJ27f/04CB/K3AhT32h/DHdEzWU=", + "dev": true + }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -4092,6 +4190,34 @@ "sisteransi": "^1.0.0" } }, + "proxy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/proxy/-/proxy-1.0.1.tgz", + "integrity": "sha512-mM9Hl6Mbw2Iiw4WLzjtPObtxX3xdsv0Fr07Kqm+GXg0eVObKBD7mc+TMQwkv2zztk5EtyLdv0+eFNXhBfPiU8A==", + "dev": true, + "requires": { + "args": "3.0.2", + "basic-auth-parser": "0.0.2", + "debug": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "psl": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", @@ -4728,6 +4854,15 @@ } } }, + "string-similarity": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-1.1.0.tgz", + "integrity": "sha1-PGZJiFikZex8QMfYFzm72ZWQSRQ=", + "dev": true, + "requires": { + "lodash": "^4.13.1" + } + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -4896,6 +5031,11 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/packages/github/package.json b/packages/github/package.json index d3942b73..5733b170 100644 --- a/packages/github/package.json +++ b/packages/github/package.json @@ -1,6 +1,6 @@ { "name": "@actions/github", - "version": "2.0.1", + "version": "2.0.2", "description": "Actions github lib", "keywords": [ "github", @@ -37,10 +37,12 @@ "url": "https://github.com/actions/toolkit/issues" }, "dependencies": { + "@actions/http-client": "^1.0.2", "@octokit/graphql": "^4.3.1", "@octokit/rest": "^16.15.0" }, "devDependencies": { - "jest": "^24.7.1" + "jest": "^24.7.1", + "proxy": "^1.0.1" } } diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index fdf19f1c..e07790f1 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -4,10 +4,15 @@ import {graphql} from '@octokit/graphql' // we need this type to set up a property on the GitHub object // that has token authorization // (it is not exported from octokit by default) -import {graphql as GraphQL} from '@octokit/graphql/dist-types/types' +import { + graphql as GraphQL, + RequestParameters as GraphQLRequestParameters +} from '@octokit/graphql/dist-types/types' import Octokit from '@octokit/rest' import * as Context from './context' +import * as http from 'http' +import {HttpClient} from '@actions/http-client' // We need this in order to extend Octokit Octokit.prototype = new Octokit() @@ -17,11 +22,113 @@ export const context = new Context.Context() export class GitHub extends Octokit { graphql: GraphQL - constructor(token: string, opts: Omit = {}) { - super({...opts, auth: `token ${token}`}) + /* eslint-disable no-dupe-class-members */ + // Disable no-dupe-class-members due to false positive for method overload + // https://github.com/typescript-eslint/typescript-eslint/issues/291 - this.graphql = graphql.defaults({ - headers: {authorization: `token ${token}`} - }) + /** + * Sets up the REST client and GraphQL client with auth and proxy support. + * The parameter `token` or `opts.auth` must be supplied. The GraphQL client + * authorization is not setup when `opts.auth` is a function or object. + * + * @param token Auth token + * @param opts Octokit options + */ + constructor(token: string, opts?: Omit) + constructor(opts: Octokit.Options) + constructor(token: string | Octokit.Options, opts?: Octokit.Options) { + super(GitHub.getOctokitOptions(GitHub.disambiguate(token, opts))) + + this.graphql = GitHub.getGraphQL(GitHub.disambiguate(token, opts)) + } + + /** + * Disambiguates the constructor overload parameters + */ + private static disambiguate( + token: string | Octokit.Options, + opts?: Octokit.Options + ): [string, Octokit.Options] { + return [ + typeof token === 'string' ? token : '', + typeof token === 'object' ? token : opts || {} + ] + } + + private static getOctokitOptions( + args: [string, Octokit.Options] + ): Octokit.Options { + const token = args[0] + const options = {...args[1]} // Shallow clone - don't mutate the object provided by the caller + + // Auth + const auth = GitHub.getAuthString(token, options) + if (auth) { + options.auth = auth + } + + // Proxy + const agent = GitHub.getProxyAgent(options) + if (agent) { + // Shallow clone - don't mutate the object provided by the caller + options.request = options.request ? {...options.request} : {} + + // Set the agent + options.request.agent = agent + } + + return options + } + + private static getGraphQL(args: [string, Octokit.Options]): GraphQL { + const defaults: GraphQLRequestParameters = {} + const token = args[0] + const options = args[1] + + // Authorization + const auth = this.getAuthString(token, options) + if (auth) { + defaults.headers = { + authorization: auth + } + } + + // Proxy + const agent = GitHub.getProxyAgent(options) + if (agent) { + defaults.request = {agent} + } + + return graphql.defaults(defaults) + } + + private static getAuthString( + token: string, + options: Octokit.Options + ): string | undefined { + // Validate args + if (!token && !options.auth) { + throw new Error('Parameter token or opts.auth is required') + } else if (token && options.auth) { + throw new Error( + 'Parameters token and opts.auth may not both be specified' + ) + } + + return typeof options.auth === 'string' ? options.auth : `token ${token}` + } + + private static getProxyAgent( + options: Octokit.Options + ): http.Agent | undefined { + if (!options.request?.agent) { + const proxyUrl = process.env['https_proxy'] || process.env['HTTPS_PROXY'] + if (proxyUrl) { + const httpClient = new HttpClient() + return httpClient.getAgent('https://api.github.com') + } + } + + return undefined } } diff --git a/packages/github/tsconfig.json b/packages/github/tsconfig.json index d68a7710..a8b812a6 100644 --- a/packages/github/tsconfig.json +++ b/packages/github/tsconfig.json @@ -2,7 +2,6 @@ "extends": "../../tsconfig.json", "compilerOptions": { "baseUrl": "./", - "esModuleInterop": true, "outDir": "./lib", "rootDir": "./src" }, diff --git a/packages/glob/__tests__/internal-pattern.test.ts b/packages/glob/__tests__/internal-pattern.test.ts index c6a1b2c8..5a2fbcc3 100644 --- a/packages/glob/__tests__/internal-pattern.test.ts +++ b/packages/glob/__tests__/internal-pattern.test.ts @@ -1,17 +1,9 @@ import * as io from '../../io/src/io' +import * as os from 'os' import * as path from 'path' import {MatchKind} from '../src/internal-match-kind' import {promises as fs} from 'fs' - -// Mock 'os' before importing Pattern -/* eslint-disable import/first */ -/* eslint-disable @typescript-eslint/promise-function-async */ -// Note, @typescript-eslint/promise-function-async is a false positive due to the -// mock factory delegate which returns any. Fixed in a future version of jest. -jest.mock('os', () => jest.requireActual('os')) -const os = jest.requireMock('os') import {Pattern} from '../src/internal-pattern' -jest.resetModuleRegistry() const IS_WINDOWS = process.platform === 'win32' @@ -32,19 +24,13 @@ describe('pattern', () => { }) it('escapes homedir', async () => { - const originalHomedir = os.homedir const home = path.join(getTestTemp(), 'home-with-[and]') await fs.mkdir(home, {recursive: true}) - try { - os.homedir = () => home - const pattern = new Pattern('~/m*') + const pattern = new Pattern('~/m*', undefined, home) - expect(pattern.searchPath).toBe(home) - expect(pattern.match(path.join(home, 'match'))).toBeTruthy() - expect(pattern.match(path.join(home, 'not-match'))).toBeFalsy() - } finally { - os.homedir = originalHomedir - } + expect(pattern.searchPath).toBe(home) + expect(pattern.match(path.join(home, 'match'))).toBeTruthy() + expect(pattern.match(path.join(home, 'not-match'))).toBeFalsy() }) it('escapes root', async () => { diff --git a/packages/glob/package-lock.json b/packages/glob/package-lock.json index 043765ec..3eb24c1b 100644 --- a/packages/glob/package-lock.json +++ b/packages/glob/package-lock.json @@ -4,11 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@actions/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.1.tgz", - "integrity": "sha512-xD+CQd9p4lU7ZfRqmUcbJpqR+Ss51rJRVeXMyOLrZQImN9/8Sy/BEUBnHO/UKD3z03R686PVTLfEPmkropGuLw==" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", diff --git a/packages/glob/src/internal-path-helper.ts b/packages/glob/src/internal-path-helper.ts index 7d9d0ef4..0931bd2c 100644 --- a/packages/glob/src/internal-path-helper.ts +++ b/packages/glob/src/internal-path-helper.ts @@ -1,5 +1,5 @@ -import * as assert from 'assert' import * as path from 'path' +import assert from 'assert' const IS_WINDOWS = process.platform === 'win32' diff --git a/packages/glob/src/internal-path.ts b/packages/glob/src/internal-path.ts index 789cb118..47001d5a 100644 --- a/packages/glob/src/internal-path.ts +++ b/packages/glob/src/internal-path.ts @@ -1,6 +1,6 @@ -import * as assert from 'assert' import * as path from 'path' import * as pathHelper from './internal-path-helper' +import assert from 'assert' const IS_WINDOWS = process.platform === 'win32' diff --git a/packages/glob/src/internal-pattern.ts b/packages/glob/src/internal-pattern.ts index 2735ca73..348acca8 100644 --- a/packages/glob/src/internal-pattern.ts +++ b/packages/glob/src/internal-pattern.ts @@ -1,7 +1,7 @@ -import * as assert from 'assert' import * as os from 'os' import * as path from 'path' import * as pathHelper from './internal-path-helper' +import assert from 'assert' import {Minimatch, IMinimatch, IOptions as IMinimatchOptions} from 'minimatch' import {MatchKind} from './internal-match-kind' import {Path} from './internal-path' @@ -48,8 +48,13 @@ export class Pattern { // https://github.com/typescript-eslint/typescript-eslint/issues/291 constructor(pattern: string) + constructor(pattern: string, segments: undefined, homedir: string) constructor(negate: boolean, segments: string[]) - constructor(patternOrNegate: string | boolean, segments?: string[]) { + constructor( + patternOrNegate: string | boolean, + segments?: string[], + homedir?: string + ) { // Pattern overload let pattern: string if (typeof patternOrNegate === 'string') { @@ -78,7 +83,7 @@ export class Pattern { } // Normalize slashes and ensures absolute root - pattern = Pattern.fixupPattern(pattern) + pattern = Pattern.fixupPattern(pattern, homedir) // Segments this.segments = new Path(pattern).segments @@ -177,7 +182,7 @@ export class Pattern { /** * Normalizes slashes and ensures absolute root */ - private static fixupPattern(pattern: string): string { + private static fixupPattern(pattern: string, homedir?: string): string { // Empty assert(pattern, 'pattern cannot be empty') @@ -206,7 +211,7 @@ export class Pattern { } // Replace leading `~` segment else if (pattern === '~' || pattern.startsWith(`~${path.sep}`)) { - const homedir = os.homedir() + homedir = homedir || os.homedir() assert(homedir, 'Unable to determine HOME directory') assert( pathHelper.hasAbsoluteRoot(homedir), diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index 543280a5..a2890085 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -1,8 +1,8 @@ import * as fs from 'fs' -import * as nock from 'nock' import * as path from 'path' import * as io from '@actions/io' import * as exec from '@actions/exec' +import nock from 'nock' const cachePath = path.join(__dirname, 'CACHE') const tempPath = path.join(__dirname, 'TEMP') diff --git a/packages/tool-cache/package-lock.json b/packages/tool-cache/package-lock.json index 2ec8bf90..129e3dfa 100644 --- a/packages/tool-cache/package-lock.json +++ b/packages/tool-cache/package-lock.json @@ -1,31 +1,16 @@ { "name": "@actions/tool-cache", - "version": "1.3.0", + "version": "1.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { - "@actions/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.1.tgz", - "integrity": "sha512-xD+CQd9p4lU7ZfRqmUcbJpqR+Ss51rJRVeXMyOLrZQImN9/8Sy/BEUBnHO/UKD3z03R686PVTLfEPmkropGuLw==" - }, - "@actions/exec": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.3.tgz", - "integrity": "sha512-TogJGnueOmM7ntCi0ASTUj4LapRRtDfj57Ja4IhPmg2fls28uVOPbAn8N+JifaOumN2UG3oEO/Ixek2A4NcYSA==", - "requires": { - "@actions/io": "^1.0.1" - } - }, "@actions/http-client": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.1.tgz", - "integrity": "sha512-vy5DhqTJ1gtEkpRrD/6BHhUlkeyccrOX0BT9KmtO5TWxe5KSSwVHFE+J15Z0dG+tJwZJ/nHC4slUIyqpkahoMg==" - }, - "@actions/io": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz", - "integrity": "sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg==" + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.2.tgz", + "integrity": "sha512-ngdGx7aXM7i9BFT+7e3RWWAEt3bX4tKrdI5w5hf0wYpHz66u5Nw6AFSFXG5wzQyUQbkgeNRnJZyK2zciGqXgrQ==", + "requires": { + "tunnel": "0.0.6" + } }, "@types/nock": { "version": "10.0.3", @@ -194,6 +179,11 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", diff --git a/packages/tool-cache/package.json b/packages/tool-cache/package.json index 990c5d85..a9d10451 100644 --- a/packages/tool-cache/package.json +++ b/packages/tool-cache/package.json @@ -1,6 +1,6 @@ { "name": "@actions/tool-cache", - "version": "1.3.0", + "version": "1.3.1", "description": "Actions tool-cache lib", "keywords": [ "github", @@ -38,7 +38,7 @@ "dependencies": { "@actions/core": "^1.2.0", "@actions/exec": "^1.0.0", - "@actions/http-client": "^1.0.1", + "@actions/http-client": "^1.0.2", "@actions/io": "^1.0.1", "semver": "^6.1.0", "uuid": "^3.3.2" diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index b91cf1ad..6e8c6c2a 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -5,7 +5,7 @@ import * as os from 'os' import * as path from 'path' import * as httpm from '@actions/http-client' import * as semver from 'semver' -import * as uuidV4 from 'uuid/v4' +import uuidV4 from 'uuid/v4' import {exec} from '@actions/exec/lib/exec' import {ExecOptions} from '@actions/exec/lib/interfaces' import {ok} from 'assert' diff --git a/tsconfig.json b/tsconfig.json index 80c954ed..a69cbc2e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "esModuleInterop": true, "module": "commonjs", "strict": true, "declaration": true,