From d7c1f88525a5ea86470d2950299b265402f8e44b Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Thu, 7 May 2020 10:11:08 -0400 Subject: [PATCH 01/11] Rebuild to use Octokit Core --- packages/github/package-lock.json | 173 ++++++++++++++++++------------ packages/github/package.json | 4 +- packages/github/src/github.ts | 58 ++++++---- 3 files changed, 143 insertions(+), 92 deletions(-) diff --git a/packages/github/package-lock.json b/packages/github/package-lock.json index a075eac212..8d62672bce 100644 --- a/packages/github/package-lock.json +++ b/packages/github/package-lock.json @@ -464,6 +464,76 @@ "@octokit/types": "^2.0.0" } }, + "@octokit/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-2.5.0.tgz", + "integrity": "sha512-uvzmkemQrBgD8xuGbjhxzJN1darJk9L2cS+M99cHrDG2jlSVpxNJVhoV86cXdYBqdHCc9Z995uLCczaaHIYA6Q==", + "requires": { + "@octokit/auth-token": "^2.4.0", + "@octokit/graphql": "^4.3.1", + "@octokit/request": "^5.4.0", + "@octokit/types": "^2.0.0", + "before-after-hook": "^2.1.0", + "universal-user-agent": "^5.0.0" + }, + "dependencies": { + "@octokit/endpoint": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz", + "integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==", + "requires": { + "@octokit/types": "^2.11.1", + "is-plain-object": "^3.0.0", + "universal-user-agent": "^5.0.0" + }, + "dependencies": { + "@octokit/types": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz", + "integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==", + "requires": { + "@types/node": ">= 8" + } + } + } + }, + "@octokit/request": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz", + "integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==", + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.0.0", + "@octokit/types": "^2.11.1", + "deprecation": "^2.0.0", + "is-plain-object": "^3.0.0", + "node-fetch": "^2.3.0", + "once": "^1.4.0", + "universal-user-agent": "^5.0.0" + }, + "dependencies": { + "@octokit/types": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz", + "integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==", + "requires": { + "@types/node": ">= 8" + } + } + } + }, + "@octokit/request-error": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.0.tgz", + "integrity": "sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==", + "requires": { + "@octokit/types": "^2.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + } + } + }, "@octokit/endpoint": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.5.1.tgz", @@ -505,25 +575,40 @@ } }, "@octokit/plugin-paginate-rest": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz", - "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.2.0.tgz", + "integrity": "sha512-KoNxC3PLNar8UJwR+1VMQOw2IoOrrFdo5YOiDKnBhpVbKpw+zkBKNMNKwM44UWL25Vkn0Sl3nYIEGKY+gW5ebw==", "requires": { - "@octokit/types": "^2.0.1" + "@octokit/types": "^2.12.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.12.2.tgz", + "integrity": "sha512-1GHLI/Jll3j6F0GbYyZPFTcHZMGjAiRfkTEoRUyaVVk2IWbDdwEiClAJvXzfXCDayuGSNCqAUH8lpjZtqW9GDw==", + "requires": { + "@types/node": ">= 8" + } + } } }, - "@octokit/plugin-request-log": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz", - "integrity": "sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw==" - }, "@octokit/plugin-rest-endpoint-methods": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz", - "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-3.10.0.tgz", + "integrity": "sha512-Z2DBsdnkWKuVBVFiLoEUKP/82ylH4Ij5F1Mss106hnQYXTxDfCWAyHW+hJ6ophuHVJ9Flaaue3fYn4CggzkHTg==", "requires": { - "@octokit/types": "^2.0.1", + "@octokit/types": "^2.14.0", "deprecation": "^2.3.1" + }, + "dependencies": { + "@octokit/types": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz", + "integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==", + "requires": { + "@types/node": ">= 8" + } + } } }, "@octokit/request": { @@ -561,29 +646,6 @@ "once": "^1.4.0" } }, - "@octokit/rest": { - "version": "16.43.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.1.tgz", - "integrity": "sha512-gfFKwRT/wFxq5qlNjnW2dh+qh74XgTQ2B179UX5K1HYCluioWj8Ndbgqw2PVqa1NnVJkGHp2ovMpVn/DImlmkw==", - "requires": { - "@octokit/auth-token": "^2.4.0", - "@octokit/plugin-paginate-rest": "^1.1.1", - "@octokit/plugin-request-log": "^1.0.0", - "@octokit/plugin-rest-endpoint-methods": "2.4.0", - "@octokit/request": "^5.2.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": "^4.0.0" - } - }, "@octokit/types": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.0.2.tgz", @@ -921,11 +983,6 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, - "atob-lite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", - "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=" - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -1124,11 +1181,6 @@ "node-int64": "^0.4.0" } }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" - }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -3031,27 +3083,12 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" - }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" - }, "lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -3413,10 +3450,10 @@ } } }, - "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==" + "octokit-plugin-action-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/octokit-plugin-action-context/-/octokit-plugin-action-context-1.0.0.tgz", + "integrity": "sha512-un0gUOVP2urVLmDBUnVDvB7d3z3QQnlZ+FlGzZ54of3lyTlpjeJ3vyklUKk6PtSOCUmGD2j3CJElQtdQjp9log==" }, "once": { "version": "1.4.0", @@ -4615,9 +4652,9 @@ } }, "universal-user-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz", - "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-5.0.0.tgz", + "integrity": "sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==", "requires": { "os-name": "^3.1.0" } diff --git a/packages/github/package.json b/packages/github/package.json index ef58523ba6..e920fe6131 100644 --- a/packages/github/package.json +++ b/packages/github/package.json @@ -38,8 +38,10 @@ }, "dependencies": { "@actions/http-client": "^1.0.3", + "@octokit/core": "^2.5.0", "@octokit/graphql": "^4.3.1", - "@octokit/rest": "^16.43.1" + "@octokit/plugin-paginate-rest": "^2.2.0", + "@octokit/plugin-rest-endpoint-methods": "^3.10.0" }, "devDependencies": { "jest": "^25.1.0", diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index 699998dc69..19df5b4156 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -1,4 +1,8 @@ -// Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/github.ts +// we need this to setup our constructors, it is not exported by default +import {OctokitOptions} from '@octokit/core/dist-types/types' +import * as Context from './context' +import * as http from 'http' +import * as httpClient from '@actions/http-client' import {graphql} from '@octokit/graphql' // we need this type to set up a property on the GitHub object @@ -9,19 +13,19 @@ import { 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 * as httpClient from '@actions/http-client' - -// We need this in order to extend Octokit -Octokit.prototype = new Octokit() +// octokit + plugins +import { Octokit as Core } from "@octokit/core"; +import { restEndpointMethods } from "@octokit/plugin-rest-endpoint-methods" +import { paginateRest } from "@octokit/plugin-paginate-rest" export const context = new Context.Context() -export class GitHub extends Octokit { - graphql: GraphQL +const Octokit = Core.plugin(restEndpointMethods, paginateRest).defaults( + { + agent: getDefaultProxyAgent() + }) +export class GitHub extends Octokit { /* 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 @@ -34,11 +38,10 @@ export class GitHub extends Octokit { * @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) { + constructor(token: string, opts?: Omit) + constructor(opts: OctokitOptions) + constructor(token: string | OctokitOptions, opts?: OctokitOptions) { super(GitHub.getOctokitOptions(GitHub.disambiguate(token, opts))) - this.graphql = GitHub.getGraphQL(GitHub.disambiguate(token, opts)) } @@ -46,9 +49,9 @@ export class GitHub extends Octokit { * Disambiguates the constructor overload parameters */ private static disambiguate( - token: string | Octokit.Options, - opts?: Octokit.Options - ): [string, Octokit.Options] { + token: string | OctokitOptions, + opts?: OctokitOptions + ): [string, OctokitOptions] { return [ typeof token === 'string' ? token : '', typeof token === 'object' ? token : opts || {} @@ -56,8 +59,8 @@ export class GitHub extends Octokit { } private static getOctokitOptions( - args: [string, Octokit.Options] - ): Octokit.Options { + args: [string, OctokitOptions] + ): OctokitOptions { const token = args[0] const options = {...args[1]} // Shallow clone - don't mutate the object provided by the caller @@ -83,7 +86,7 @@ export class GitHub extends Octokit { return options } - private static getGraphQL(args: [string, Octokit.Options]): GraphQL { + private static getGraphQL(args: [string, OctokitOptions]): GraphQL { const defaults: GraphQLRequestParameters = {} defaults.baseUrl = this.getGraphQLBaseUrl() const token = args[0] @@ -108,7 +111,7 @@ export class GitHub extends Octokit { private static getAuthString( token: string, - options: Octokit.Options + options: OctokitOptions ): string | undefined { // Validate args if (!token && !options.auth) { @@ -124,9 +127,9 @@ export class GitHub extends Octokit { private static getProxyAgent( destinationUrl: string, - options: Octokit.Options + options: OctokitOptions ): http.Agent | undefined { - if (!options.request?.agent) { + if (!options.request || !options.request.agent) { if (httpClient.getProxyUrl(destinationUrl)) { const hc = new httpClient.HttpClient() return hc.getAgent(destinationUrl) @@ -156,3 +159,12 @@ export class GitHub extends Octokit { return url } } + +function getDefaultProxyAgent() : http.Agent | undefined +{ + const serverUrl = 'https://api.github.com' + if (httpClient.getProxyUrl(serverUrl)) { + const hc = new httpClient.HttpClient() + return hc.getAgent(serverUrl) + } +} From 618498d6dfe4685577d4721341e5ba3cc16bfcc7 Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Thu, 7 May 2020 15:06:34 -0400 Subject: [PATCH 02/11] Example Enterprise Solution --- packages/github/__tests__/github.test.ts | 32 ++++- packages/github/package-lock.json | 13 +- packages/github/package.json | 1 + packages/github/src/github.ts | 167 ++++------------------- packages/github/src/internal/utils.ts | 124 +++++++++++++++++ 5 files changed, 188 insertions(+), 149 deletions(-) create mode 100644 packages/github/src/internal/utils.ts diff --git a/packages/github/__tests__/github.test.ts b/packages/github/__tests__/github.test.ts index bf81b07ace..68feb80e0e 100644 --- a/packages/github/__tests__/github.test.ts +++ b/packages/github/__tests__/github.test.ts @@ -1,6 +1,6 @@ import * as http from 'http' import proxy from 'proxy' -import {GitHub} from '../src/github' +import {GitHub, GitHubEnterprise} from '../src/github' describe('@actions/github', () => { const proxyUrl = 'http://127.0.0.1:8080' @@ -158,6 +158,36 @@ describe('@actions/github', () => { expect(proxyConnects).toEqual(['api.github.com:443']) }) + it('basic REST client enterprise', async () => { + const token = getToken() + if (!token) { + return + } + + const octokit = new GitHubEnterprise(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 enterprise call', async () => { + const token = getToken() + if (!token) { + return + } + const octokit = new GitHubEnterprise(token) + // will fail endpoint does not exist on dotcom, but it makes the call + try { + await octokit.enterpriseAdmin.checkMaintenanceStatus() + } catch (error) { + expect(error.toString()).toBe('HttpError: Not Found') + } + }) + function getToken(): string { const token = process.env['GITHUB_TOKEN'] || '' if (!token && first) { diff --git a/packages/github/package-lock.json b/packages/github/package-lock.json index 8d62672bce..477105ad79 100644 --- a/packages/github/package-lock.json +++ b/packages/github/package-lock.json @@ -574,6 +574,14 @@ } } }, + "@octokit/plugin-enterprise-server": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-server/-/plugin-enterprise-server-7.4.1.tgz", + "integrity": "sha512-lbuur11bnczaaO/HoEvLFErwkawWPO+prWBK1MMISc39ZsRcmwYfxfXyybQdeBC4cG1AaoFN0rTaw8kXPgtQ8g==", + "requires": { + "@octokit/types": "^2.0.2" + } + }, "@octokit/plugin-paginate-rest": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.2.0.tgz", @@ -3450,11 +3458,6 @@ } } }, - "octokit-plugin-action-context": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/octokit-plugin-action-context/-/octokit-plugin-action-context-1.0.0.tgz", - "integrity": "sha512-un0gUOVP2urVLmDBUnVDvB7d3z3QQnlZ+FlGzZ54of3lyTlpjeJ3vyklUKk6PtSOCUmGD2j3CJElQtdQjp9log==" - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", diff --git a/packages/github/package.json b/packages/github/package.json index e920fe6131..2d42d899a2 100644 --- a/packages/github/package.json +++ b/packages/github/package.json @@ -40,6 +40,7 @@ "@actions/http-client": "^1.0.3", "@octokit/core": "^2.5.0", "@octokit/graphql": "^4.3.1", + "@octokit/plugin-enterprise-server": "^7.4.1", "@octokit/plugin-paginate-rest": "^2.2.0", "@octokit/plugin-rest-endpoint-methods": "^3.10.0" }, diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index 19df5b4156..fdedc335e1 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -1,30 +1,16 @@ -// we need this to setup our constructors, it is not exported by default -import {OctokitOptions} from '@octokit/core/dist-types/types' import * as Context from './context' -import * as http from 'http' -import * as httpClient from '@actions/http-client' -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, - RequestParameters as GraphQLRequestParameters -} from '@octokit/graphql/dist-types/types' +import {OctokitOptions} from '@octokit/core/dist-types/types' +import * as Utils from './internal/utils' // octokit + plugins -import { Octokit as Core } from "@octokit/core"; -import { restEndpointMethods } from "@octokit/plugin-rest-endpoint-methods" -import { paginateRest } from "@octokit/plugin-paginate-rest" +import {Octokit as Core} from '@octokit/core' +import {restEndpointMethods} from '@octokit/plugin-rest-endpoint-methods' +import {paginateRest} from '@octokit/plugin-paginate-rest' +import {enterpriseServer220Admin} from '@octokit/plugin-enterprise-server' export const context = new Context.Context() - -const Octokit = Core.plugin(restEndpointMethods, paginateRest).defaults( - { - agent: getDefaultProxyAgent() - }) - +const OctokitEnterprise = Core.plugin(paginateRest, enterpriseServer220Admin) +const Octokit = Core.plugin(paginateRest, restEndpointMethods) export class GitHub extends Octokit { /* eslint-disable no-dupe-class-members */ // Disable no-dupe-class-members due to false positive for method overload @@ -41,130 +27,25 @@ export class GitHub extends Octokit { constructor(token: string, opts?: Omit) constructor(opts: OctokitOptions) constructor(token: string | OctokitOptions, opts?: OctokitOptions) { - super(GitHub.getOctokitOptions(GitHub.disambiguate(token, opts))) - this.graphql = GitHub.getGraphQL(GitHub.disambiguate(token, opts)) + super(Utils.getOctokitOptions(Utils.disambiguate(token, opts))) + this.graphql = Utils.getGraphQL(Utils.disambiguate(token, opts)) } +} +export class GitHubEnterprise extends OctokitEnterprise { /** - * Disambiguates the constructor overload parameters + * 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 + * @param version the version of the GitHubEnterprise */ - private static disambiguate( - token: string | OctokitOptions, - opts?: OctokitOptions - ): [string, OctokitOptions] { - return [ - typeof token === 'string' ? token : '', - typeof token === 'object' ? token : opts || {} - ] - } - - private static getOctokitOptions( - args: [string, OctokitOptions] - ): OctokitOptions { - const token = args[0] - const options = {...args[1]} // Shallow clone - don't mutate the object provided by the caller - - // Base URL - GHES or Dotcom - options.baseUrl = options.baseUrl || this.getApiBaseUrl() - - // Auth - const auth = GitHub.getAuthString(token, options) - if (auth) { - options.auth = auth - } - - // Proxy - const agent = GitHub.getProxyAgent(options.baseUrl, 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, OctokitOptions]): GraphQL { - const defaults: GraphQLRequestParameters = {} - defaults.baseUrl = this.getGraphQLBaseUrl() - 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(defaults.baseUrl, options) - if (agent) { - defaults.request = {agent} - } - - return graphql.defaults(defaults) - } - - private static getAuthString( - token: string, - options: OctokitOptions - ): 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( - destinationUrl: string, - options: OctokitOptions - ): http.Agent | undefined { - if (!options.request || !options.request.agent) { - if (httpClient.getProxyUrl(destinationUrl)) { - const hc = new httpClient.HttpClient() - return hc.getAgent(destinationUrl) - } - } - - return undefined - } - - private static getApiBaseUrl(): string { - return process.env['GITHUB_API_URL'] || 'https://api.github.com' - } - - private static getGraphQLBaseUrl(): string { - let url = - process.env['GITHUB_GRAPHQL_URL'] || 'https://api.github.com/graphql' - - // Shouldn't be a trailing slash, but remove if so - if (url.endsWith('/')) { - url = url.substr(0, url.length - 1) - } - - // Remove trailing "/graphql" - if (url.toUpperCase().endsWith('/GRAPHQL')) { - url = url.substr(0, url.length - '/graphql'.length) - } - return url - } -} - -function getDefaultProxyAgent() : http.Agent | undefined -{ - const serverUrl = 'https://api.github.com' - if (httpClient.getProxyUrl(serverUrl)) { - const hc = new httpClient.HttpClient() - return hc.getAgent(serverUrl) + constructor(token: string, opts?: Omit) + constructor(opts: OctokitOptions) + constructor(token: string | OctokitOptions, opts?: OctokitOptions) { + super(Utils.getOctokitOptions(Utils.disambiguate(token, opts))) + this.graphql = Utils.getGraphQL(Utils.disambiguate(token, opts)) } } diff --git a/packages/github/src/internal/utils.ts b/packages/github/src/internal/utils.ts new file mode 100644 index 0000000000..314599c720 --- /dev/null +++ b/packages/github/src/internal/utils.ts @@ -0,0 +1,124 @@ +import * as http from 'http' +import * as httpClient from '@actions/http-client' +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, + RequestParameters as GraphQLRequestParameters +} from '@octokit/graphql/dist-types/types' +import {OctokitOptions} from '@octokit/core/dist-types/types' + +/** + * Disambiguates the constructor overload parameters + */ +export function disambiguate( + token: string | OctokitOptions, + opts?: OctokitOptions +): [string, OctokitOptions] { + return [ + typeof token === 'string' ? token : '', + typeof token === 'object' ? token : opts || {} + ] +} + +export function getOctokitOptions( + args: [string, OctokitOptions] +): OctokitOptions { + const token = args[0] + const options = {...args[1]} // Shallow clone - don't mutate the object provided by the caller + + // Base URL - GHES or Dotcom + options.baseUrl = options.baseUrl || getApiBaseUrl() + + // Auth + const auth = getAuthString(token, options) + if (auth) { + options.auth = auth + } + + // Proxy + const agent = getProxyAgent(options.baseUrl, 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 +} + +export function getGraphQL(args: [string, OctokitOptions]): GraphQL { + const defaults: GraphQLRequestParameters = {} + defaults.baseUrl = getGraphQLBaseUrl() + const token = args[0] + const options = args[1] + + // Authorization + const auth = getAuthString(token, options) + if (auth) { + defaults.headers = { + authorization: auth + } + } + + // Proxy + const agent = getProxyAgent(defaults.baseUrl, options) + if (agent) { + defaults.request = {agent} + } + + return graphql.defaults(defaults) +} + +export function getAuthString( + token: string, + options: OctokitOptions +): 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}` +} + +export function getProxyAgent( + destinationUrl: string, + options: OctokitOptions +): http.Agent | undefined { + if (!options.request || !options.request.agent) { + if (httpClient.getProxyUrl(destinationUrl)) { + const hc = new httpClient.HttpClient() + return hc.getAgent(destinationUrl) + } + } + + return undefined +} + +export function getApiBaseUrl(): string { + return process.env['GITHUB_API_URL'] || 'https://api.github.com' +} + +export function getGraphQLBaseUrl(): string { + let url = + process.env['GITHUB_GRAPHQL_URL'] || 'https://api.github.com/graphql' + + // Shouldn't be a trailing slash, but remove if so + if (url.endsWith('/')) { + url = url.substr(0, url.length - 1) + } + + // Remove trailing "/graphql" + if (url.toUpperCase().endsWith('/GRAPHQL')) { + url = url.substr(0, url.length - '/graphql'.length) + } + return url +} From dbbbdffcc791f6c6dda2d0ff8dcab1e2527e8b24 Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Fri, 8 May 2020 16:49:24 -0400 Subject: [PATCH 03/11] implement defaults, cleanup --- .../github/__tests__/github.proxy.test.ts | 109 ++++++++++++++++++ packages/github/__tests__/github.test.ts | 65 +---------- packages/github/package-lock.json | 2 +- packages/github/package.json | 3 +- packages/github/src/github.ts | 52 +++++---- packages/github/src/internal/utils.ts | 21 +--- 6 files changed, 148 insertions(+), 104 deletions(-) create mode 100644 packages/github/__tests__/github.proxy.test.ts diff --git a/packages/github/__tests__/github.proxy.test.ts b/packages/github/__tests__/github.proxy.test.ts new file mode 100644 index 0000000000..45a7c8f958 --- /dev/null +++ b/packages/github/__tests__/github.proxy.test.ts @@ -0,0 +1,109 @@ +import * as http from 'http' +import * as https from 'https' +import proxy from 'proxy' + +// Default values are set when the module is imported, so we need to set proxy first. +const proxyUrl = 'http://127.0.0.1:8081' +const originalProxyUrl = process.env['https_proxy'] +process.env['https_proxy'] = proxyUrl +// eslint-disable-next-line import/first +import {GitHub} from '../src/github' + +describe('@actions/github', () => { + let proxyConnects: string[] + let proxyServer: http.Server + let first = true + + beforeAll(async () => { + // Start proxy server + proxyServer = proxy() + await new Promise(resolve => { + const port = Number(proxyUrl.split(':')[2]) + proxyServer.listen(port, () => resolve()) + }) + proxyServer.on('connect', req => { + proxyConnects.push(req.url) + }) + }) + + beforeEach(() => { + 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 with proxy', 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).toEqual(['api.github.com:443']) + }) + + 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']) + }) + + it('should only use default agent if one is not provided', async () => { + const token = getToken() + if (!token) { + return + } + + // Valid token + const octokit = new GitHub(token, { + request: { + agent: new https.Agent() + } + }) + const branch = await octokit.repos.getBranch({ + owner: 'actions', + repo: 'toolkit', + branch: 'master' + }) + expect(branch.data.name).toBe('master') + expect(proxyConnects).toHaveLength(0) + }) + + 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__/github.test.ts b/packages/github/__tests__/github.test.ts index 68feb80e0e..0faabed36a 100644 --- a/packages/github/__tests__/github.test.ts +++ b/packages/github/__tests__/github.test.ts @@ -1,6 +1,6 @@ import * as http from 'http' import proxy from 'proxy' -import {GitHub, GitHubEnterprise} from '../src/github' +import {GitHub} from '../src/github' describe('@actions/github', () => { const proxyUrl = 'http://127.0.0.1:8080' @@ -43,7 +43,6 @@ describe('@actions/github', () => { if (!token) { return } - const octokit = new GitHub(token) const branch = await octokit.repos.getBranch({ owner: 'actions', @@ -85,23 +84,6 @@ describe('@actions/github', () => { 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) { @@ -143,51 +125,6 @@ describe('@actions/github', () => { 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']) - }) - - it('basic REST client enterprise', async () => { - const token = getToken() - if (!token) { - return - } - - const octokit = new GitHubEnterprise(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 enterprise call', async () => { - const token = getToken() - if (!token) { - return - } - const octokit = new GitHubEnterprise(token) - // will fail endpoint does not exist on dotcom, but it makes the call - try { - await octokit.enterpriseAdmin.checkMaintenanceStatus() - } catch (error) { - expect(error.toString()).toBe('HttpError: Not Found') - } - }) - function getToken(): string { const token = process.env['GITHUB_TOKEN'] || '' if (!token && first) { diff --git a/packages/github/package-lock.json b/packages/github/package-lock.json index 477105ad79..776542b869 100644 --- a/packages/github/package-lock.json +++ b/packages/github/package-lock.json @@ -1,6 +1,6 @@ { "name": "@actions/github", - "version": "2.2.0", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/github/package.json b/packages/github/package.json index 2d42d899a2..68a0371b19 100644 --- a/packages/github/package.json +++ b/packages/github/package.json @@ -1,6 +1,6 @@ { "name": "@actions/github", - "version": "2.2.0", + "version": "3.0.0", "description": "Actions github lib", "keywords": [ "github", @@ -40,7 +40,6 @@ "@actions/http-client": "^1.0.3", "@octokit/core": "^2.5.0", "@octokit/graphql": "^4.3.1", - "@octokit/plugin-enterprise-server": "^7.4.1", "@octokit/plugin-paginate-rest": "^2.2.0", "@octokit/plugin-rest-endpoint-methods": "^3.10.0" }, diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index fdedc335e1..361778ac87 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -1,17 +1,18 @@ import * as Context from './context' -import {OctokitOptions} from '@octokit/core/dist-types/types' import * as Utils from './internal/utils' // octokit + plugins import {Octokit as Core} from '@octokit/core' +import {OctokitOptions, Constructor} from '@octokit/core/dist-types/types' import {restEndpointMethods} from '@octokit/plugin-rest-endpoint-methods' import {paginateRest} from '@octokit/plugin-paginate-rest' -import {enterpriseServer220Admin} from '@octokit/plugin-enterprise-server' + +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ export const context = new Context.Context() -const OctokitEnterprise = Core.plugin(paginateRest, enterpriseServer220Admin) -const Octokit = Core.plugin(paginateRest, restEndpointMethods) -export class GitHub extends Octokit { + +class GitHubCore extends Core { /* 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 @@ -30,22 +31,33 @@ export class GitHub extends Octokit { super(Utils.getOctokitOptions(Utils.disambiguate(token, opts))) this.graphql = Utils.getGraphQL(Utils.disambiguate(token, opts)) } + + // Base class assumes the octokit options are the first arg, that is not the case for us, so we need to reimplement + static defaults>( + this: T, + defaults: OctokitOptions + ): T { + const GitHubWithDefaults = class extends this { + constructor(...args: any[]) { + const token = args[0] + const opts = args[1] + const options = Utils.getOctokitOptions(Utils.disambiguate(token, opts)) + super(Object.assign({}, defaults, options)) + } + } + return GitHubWithDefaults + } } -export class GitHubEnterprise extends OctokitEnterprise { - /** - * 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 - * @param version the version of the GitHubEnterprise - */ - constructor(token: string, opts?: Omit) - constructor(opts: OctokitOptions) - constructor(token: string | OctokitOptions, opts?: OctokitOptions) { - super(Utils.getOctokitOptions(Utils.disambiguate(token, opts))) - this.graphql = Utils.getGraphQL(Utils.disambiguate(token, opts)) +const baseUrl = Utils.getApiBaseUrl() +const defaults = { + baseUrl, + request: { + agent: Utils.getProxyAgent(baseUrl) } } + +export const GitHub = GitHubCore.plugin( + paginateRest, + restEndpointMethods +).defaults(defaults) diff --git a/packages/github/src/internal/utils.ts b/packages/github/src/internal/utils.ts index 314599c720..734ed71d8d 100644 --- a/packages/github/src/internal/utils.ts +++ b/packages/github/src/internal/utils.ts @@ -30,25 +30,12 @@ export function getOctokitOptions( const token = args[0] const options = {...args[1]} // Shallow clone - don't mutate the object provided by the caller - // Base URL - GHES or Dotcom - options.baseUrl = options.baseUrl || getApiBaseUrl() - // Auth const auth = getAuthString(token, options) if (auth) { options.auth = auth } - // Proxy - const agent = getProxyAgent(options.baseUrl, 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 } @@ -79,7 +66,6 @@ export function getAuthString( token: string, options: OctokitOptions ): string | undefined { - // Validate args if (!token && !options.auth) { throw new Error('Parameter token or opts.auth is required') } else if (token && options.auth) { @@ -91,15 +77,16 @@ export function getAuthString( export function getProxyAgent( destinationUrl: string, - options: OctokitOptions + options?: OctokitOptions ): http.Agent | undefined { - if (!options.request || !options.request.agent) { + if (!options || !options.request || !options.request.agent) { if (httpClient.getProxyUrl(destinationUrl)) { const hc = new httpClient.HttpClient() return hc.getAgent(destinationUrl) } + } else if (options && options.request && options.request.agent) { + return options.request.agent } - return undefined } From a8c1b0364f345e15eb2194133cbd6cf93b2f5ccf Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Tue, 19 May 2020 20:57:11 -0400 Subject: [PATCH 04/11] Update @octokit/core, remove inheritance --- packages/github/README.md | 9 +- .../github/__tests__/github.proxy.test.ts | 18 ++- packages/github/__tests__/github.test.ts | 8 +- packages/github/package-lock.json | 151 ++++-------------- packages/github/package.json | 3 +- packages/github/src/github.ts | 63 +++----- packages/github/src/internal/utils.ts | 48 ------ 7 files changed, 66 insertions(+), 234 deletions(-) diff --git a/packages/github/README.md b/packages/github/README.md index ce606c1945..32c832ea8f 100644 --- a/packages/github/README.md +++ b/packages/github/README.md @@ -4,7 +4,7 @@ ## Usage -Returns an authenticated Octokit client that follows the machine [proxy settings](https://help.github.com/en/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners). 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/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners) and correctly sets GHES base urls. See https://octokit.github.io/rest.js for the API. ```js const github = require('@actions/github'); @@ -17,8 +17,9 @@ async function run() { // https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#about-the-github_token-secret const myToken = core.getInput('myToken'); - const octokit = new github.GitHub(myToken); - + const octokit = new github.GitHub(github.getOptions(myToken)); + // or you may set the authentication on the options yourself + // const octokit = new github.GitHub({auth: `token ${myToken}`}); const { data: pullRequest } = await octokit.pulls.get({ owner: 'octokit', repo: 'rest.js', @@ -34,7 +35,7 @@ async function run() { run(); ``` -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 pass client options, as specified by [Octokit](https://github.com/octokit/core.js#options), as a second argument getOptions function. You can also make GraphQL requests. See https://github.com/octokit/graphql.js for the API. diff --git a/packages/github/__tests__/github.proxy.test.ts b/packages/github/__tests__/github.proxy.test.ts index 45a7c8f958..521f1bfc96 100644 --- a/packages/github/__tests__/github.proxy.test.ts +++ b/packages/github/__tests__/github.proxy.test.ts @@ -7,7 +7,7 @@ const proxyUrl = 'http://127.0.0.1:8081' const originalProxyUrl = process.env['https_proxy'] process.env['https_proxy'] = proxyUrl // eslint-disable-next-line import/first -import {GitHub} from '../src/github' +import {GitHub, getOptions} from '../src/github' describe('@actions/github', () => { let proxyConnects: string[] @@ -48,7 +48,7 @@ describe('@actions/github', () => { return } - const octokit = new GitHub(token) + const octokit = new GitHub(getOptions(token)) const branch = await octokit.repos.getBranch({ owner: 'actions', repo: 'toolkit', @@ -64,7 +64,7 @@ describe('@actions/github', () => { return } process.env['https_proxy'] = proxyUrl - const octokit = new GitHub(token) + const octokit = new GitHub(getOptions(token)) const repository = await octokit.graphql( '{repository(owner:"actions", name:"toolkit"){name}}' @@ -80,11 +80,13 @@ describe('@actions/github', () => { } // Valid token - const octokit = new GitHub(token, { - request: { - agent: new https.Agent() - } - }) + const octokit = new GitHub( + getOptions(token, { + request: { + agent: new https.Agent() + } + }) + ) const branch = await octokit.repos.getBranch({ owner: 'actions', repo: 'toolkit', diff --git a/packages/github/__tests__/github.test.ts b/packages/github/__tests__/github.test.ts index 0faabed36a..755616ca8a 100644 --- a/packages/github/__tests__/github.test.ts +++ b/packages/github/__tests__/github.test.ts @@ -1,6 +1,6 @@ import * as http from 'http' import proxy from 'proxy' -import {GitHub} from '../src/github' +import {GitHub, getOptions} from '../src/github' describe('@actions/github', () => { const proxyUrl = 'http://127.0.0.1:8080' @@ -43,7 +43,7 @@ describe('@actions/github', () => { if (!token) { return } - const octokit = new GitHub(token) + const octokit = new GitHub(getOptions(token)) const branch = await octokit.repos.getBranch({ owner: 'actions', repo: 'toolkit', @@ -90,7 +90,7 @@ describe('@actions/github', () => { return } - const octokit = new GitHub(token) + const octokit = new GitHub(getOptions(token)) const repository = await octokit.graphql( '{repository(owner:"actions", name:"toolkit"){name}}' ) @@ -105,7 +105,7 @@ describe('@actions/github', () => { } // Valid token - let octokit = new GitHub(token) + let octokit = new GitHub(getOptions(token)) const repository = await octokit.graphql( '{repository(owner:"actions", name:"toolkit"){name}}' ) diff --git a/packages/github/package-lock.json b/packages/github/package-lock.json index 776542b869..5d0ed1b3d6 100644 --- a/packages/github/package-lock.json +++ b/packages/github/package-lock.json @@ -465,9 +465,9 @@ } }, "@octokit/core": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-2.5.0.tgz", - "integrity": "sha512-uvzmkemQrBgD8xuGbjhxzJN1darJk9L2cS+M99cHrDG2jlSVpxNJVhoV86cXdYBqdHCc9Z995uLCczaaHIYA6Q==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-2.5.2.tgz", + "integrity": "sha512-+hEKCEGvbS902uuSk/TyVnI7eWDEKVm1BIPnbKy8gsxjTYaybEU8EG73B3Ju5cMj2/OIZ0uHoQWD1nGWhWsj2g==", "requires": { "@octokit/auth-token": "^2.4.0", "@octokit/graphql": "^4.3.1", @@ -475,111 +475,26 @@ "@octokit/types": "^2.0.0", "before-after-hook": "^2.1.0", "universal-user-agent": "^5.0.0" - }, - "dependencies": { - "@octokit/endpoint": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz", - "integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==", - "requires": { - "@octokit/types": "^2.11.1", - "is-plain-object": "^3.0.0", - "universal-user-agent": "^5.0.0" - }, - "dependencies": { - "@octokit/types": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz", - "integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==", - "requires": { - "@types/node": ">= 8" - } - } - } - }, - "@octokit/request": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz", - "integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==", - "requires": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.0.0", - "@octokit/types": "^2.11.1", - "deprecation": "^2.0.0", - "is-plain-object": "^3.0.0", - "node-fetch": "^2.3.0", - "once": "^1.4.0", - "universal-user-agent": "^5.0.0" - }, - "dependencies": { - "@octokit/types": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz", - "integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==", - "requires": { - "@types/node": ">= 8" - } - } - } - }, - "@octokit/request-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.0.tgz", - "integrity": "sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==", - "requires": { - "@octokit/types": "^2.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - } } }, "@octokit/endpoint": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.5.1.tgz", - "integrity": "sha512-nBFhRUb5YzVTCX/iAK1MgQ4uWo89Gu0TH00qQHoYRCsE12dWcG1OiLd7v2EIo2+tpUKPMOQ62QFy9hy9Vg2ULg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz", + "integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==", "requires": { - "@octokit/types": "^2.0.0", + "@octokit/types": "^2.11.1", "is-plain-object": "^3.0.0", - "universal-user-agent": "^4.0.0" - }, - "dependencies": { - "universal-user-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz", - "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==", - "requires": { - "os-name": "^3.1.0" - } - } + "universal-user-agent": "^5.0.0" } }, "@octokit/graphql": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.3.1.tgz", - "integrity": "sha512-hCdTjfvrK+ilU2keAdqNBWOk+gm1kai1ZcdjRfB30oA3/T6n53UVJb7w0L5cR3/rhU91xT3HSqCd+qbvH06yxA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.4.0.tgz", + "integrity": "sha512-Du3hAaSROQ8EatmYoSAJjzAz3t79t9Opj/WY1zUgxVUGfIKn0AEjg+hlOLscF6fv6i/4y/CeUvsWgIfwMkTccw==", "requires": { "@octokit/request": "^5.3.0", "@octokit/types": "^2.0.0", - "universal-user-agent": "^4.0.0" - }, - "dependencies": { - "universal-user-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz", - "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==", - "requires": { - "os-name": "^3.1.0" - } - } - } - }, - "@octokit/plugin-enterprise-server": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-server/-/plugin-enterprise-server-7.4.1.tgz", - "integrity": "sha512-lbuur11bnczaaO/HoEvLFErwkawWPO+prWBK1MMISc39ZsRcmwYfxfXyybQdeBC4cG1AaoFN0rTaw8kXPgtQ8g==", - "requires": { - "@octokit/types": "^2.0.2" + "universal-user-agent": "^5.0.0" } }, "@octokit/plugin-paginate-rest": { @@ -620,34 +535,24 @@ } }, "@octokit/request": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.3.1.tgz", - "integrity": "sha512-5/X0AL1ZgoU32fAepTfEoggFinO3rxsMLtzhlUX+RctLrusn/CApJuGFCd0v7GMFhF+8UiCsTTfsu7Fh1HnEJg==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz", + "integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==", "requires": { - "@octokit/endpoint": "^5.5.0", - "@octokit/request-error": "^1.0.1", - "@octokit/types": "^2.0.0", + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.0.0", + "@octokit/types": "^2.11.1", "deprecation": "^2.0.0", "is-plain-object": "^3.0.0", "node-fetch": "^2.3.0", "once": "^1.4.0", - "universal-user-agent": "^4.0.0" - }, - "dependencies": { - "universal-user-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz", - "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==", - "requires": { - "os-name": "^3.1.0" - } - } + "universal-user-agent": "^5.0.0" } }, "@octokit/request-error": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.0.tgz", - "integrity": "sha512-DNBhROBYjjV/I9n7A8kVkmQNkqFAMem90dSxqvPq57e2hBr7mNTX98y3R2zDpqMQHVRpBDjsvsfIGgBzy+4PAg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.0.tgz", + "integrity": "sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==", "requires": { "@octokit/types": "^2.0.0", "deprecation": "^2.0.0", @@ -655,9 +560,9 @@ } }, "@octokit/types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.0.2.tgz", - "integrity": "sha512-StASIL2lgT3TRjxv17z9pAqbnI7HGu9DrJlg3sEBFfCLaMEqp+O3IQPUF6EZtQ4xkAu2ml6kMBBCtGxjvmtmuQ==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", "requires": { "@types/node": ">= 8" } @@ -4853,9 +4758,9 @@ "dev": true }, "windows-release": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", - "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz", + "integrity": "sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==", "requires": { "execa": "^1.0.0" } diff --git a/packages/github/package.json b/packages/github/package.json index 68a0371b19..1eab9a75c2 100644 --- a/packages/github/package.json +++ b/packages/github/package.json @@ -38,8 +38,7 @@ }, "dependencies": { "@actions/http-client": "^1.0.3", - "@octokit/core": "^2.5.0", - "@octokit/graphql": "^4.3.1", + "@octokit/core": "^2.5.1", "@octokit/plugin-paginate-rest": "^2.2.0", "@octokit/plugin-rest-endpoint-methods": "^3.10.0" }, diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index 361778ac87..f81e90cc3a 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -2,53 +2,13 @@ import * as Context from './context' import * as Utils from './internal/utils' // octokit + plugins -import {Octokit as Core} from '@octokit/core' -import {OctokitOptions, Constructor} from '@octokit/core/dist-types/types' +import {Octokit} from '@octokit/core' +import {OctokitOptions} from '@octokit/core/dist-types/types' import {restEndpointMethods} from '@octokit/plugin-rest-endpoint-methods' import {paginateRest} from '@octokit/plugin-paginate-rest' -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ - export const context = new Context.Context() -class GitHubCore extends Core { - /* 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 - - /** - * 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: OctokitOptions) - constructor(token: string | OctokitOptions, opts?: OctokitOptions) { - super(Utils.getOctokitOptions(Utils.disambiguate(token, opts))) - this.graphql = Utils.getGraphQL(Utils.disambiguate(token, opts)) - } - - // Base class assumes the octokit options are the first arg, that is not the case for us, so we need to reimplement - static defaults>( - this: T, - defaults: OctokitOptions - ): T { - const GitHubWithDefaults = class extends this { - constructor(...args: any[]) { - const token = args[0] - const opts = args[1] - const options = Utils.getOctokitOptions(Utils.disambiguate(token, opts)) - super(Object.assign({}, defaults, options)) - } - } - return GitHubWithDefaults - } -} - const baseUrl = Utils.getApiBaseUrl() const defaults = { baseUrl, @@ -57,7 +17,20 @@ const defaults = { } } -export const GitHub = GitHubCore.plugin( - paginateRest, - restEndpointMethods +export const GitHub = Octokit.plugin( + restEndpointMethods, + paginateRest ).defaults(defaults) + +/** + * Convience function to correctly format options from a token + * + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set + */ +export function getOptions( + token: string, + options?: OctokitOptions +): OctokitOptions { + return Utils.getOctokitOptions(Utils.disambiguate(token, options)) +} diff --git a/packages/github/src/internal/utils.ts b/packages/github/src/internal/utils.ts index 734ed71d8d..fe882c8be5 100644 --- a/packages/github/src/internal/utils.ts +++ b/packages/github/src/internal/utils.ts @@ -1,14 +1,5 @@ import * as http from 'http' import * as httpClient from '@actions/http-client' -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, - RequestParameters as GraphQLRequestParameters -} from '@octokit/graphql/dist-types/types' import {OctokitOptions} from '@octokit/core/dist-types/types' /** @@ -39,29 +30,6 @@ export function getOctokitOptions( return options } -export function getGraphQL(args: [string, OctokitOptions]): GraphQL { - const defaults: GraphQLRequestParameters = {} - defaults.baseUrl = getGraphQLBaseUrl() - const token = args[0] - const options = args[1] - - // Authorization - const auth = getAuthString(token, options) - if (auth) { - defaults.headers = { - authorization: auth - } - } - - // Proxy - const agent = getProxyAgent(defaults.baseUrl, options) - if (agent) { - defaults.request = {agent} - } - - return graphql.defaults(defaults) -} - export function getAuthString( token: string, options: OctokitOptions @@ -93,19 +61,3 @@ export function getProxyAgent( export function getApiBaseUrl(): string { return process.env['GITHUB_API_URL'] || 'https://api.github.com' } - -export function getGraphQLBaseUrl(): string { - let url = - process.env['GITHUB_GRAPHQL_URL'] || 'https://api.github.com/graphql' - - // Shouldn't be a trailing slash, but remove if so - if (url.endsWith('/')) { - url = url.substr(0, url.length - 1) - } - - // Remove trailing "/graphql" - if (url.toUpperCase().endsWith('/GRAPHQL')) { - url = url.substr(0, url.length - '/graphql'.length) - } - return url -} From 21a8c07ffffe0d9c15afb5f585e4afd19ee73d59 Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Wed, 20 May 2020 11:51:30 -0400 Subject: [PATCH 05/11] simplify getProxyAgent --- packages/github/src/internal/utils.ts | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/packages/github/src/internal/utils.ts b/packages/github/src/internal/utils.ts index fe882c8be5..08e8464a15 100644 --- a/packages/github/src/internal/utils.ts +++ b/packages/github/src/internal/utils.ts @@ -43,19 +43,9 @@ export function getAuthString( return typeof options.auth === 'string' ? options.auth : `token ${token}` } -export function getProxyAgent( - destinationUrl: string, - options?: OctokitOptions -): http.Agent | undefined { - if (!options || !options.request || !options.request.agent) { - if (httpClient.getProxyUrl(destinationUrl)) { - const hc = new httpClient.HttpClient() - return hc.getAgent(destinationUrl) - } - } else if (options && options.request && options.request.agent) { - return options.request.agent - } - return undefined +export function getProxyAgent(destinationUrl: string): http.Agent | undefined { + const hc = new httpClient.HttpClient() + return hc.getAgent(destinationUrl) } export function getApiBaseUrl(): string { From 3ec2a3d2a5d5f8ef20575fccf034d00fa0936fa4 Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Wed, 20 May 2020 12:01:12 -0400 Subject: [PATCH 06/11] Cleanup code --- packages/github/src/github.ts | 10 +++++++++- packages/github/src/internal/utils.ts | 28 --------------------------- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index f81e90cc3a..4008a8690c 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -32,5 +32,13 @@ export function getOptions( token: string, options?: OctokitOptions ): OctokitOptions { - return Utils.getOctokitOptions(Utils.disambiguate(token, options)) + const opts = Object.assign({}, options || {}) // Shallow clone - don't mutate the object provided by the caller + + // Auth + const auth = Utils.getAuthString(token, opts) + if (auth) { + opts.auth = auth + } + + return opts } diff --git a/packages/github/src/internal/utils.ts b/packages/github/src/internal/utils.ts index 08e8464a15..7c647a69ef 100644 --- a/packages/github/src/internal/utils.ts +++ b/packages/github/src/internal/utils.ts @@ -2,34 +2,6 @@ import * as http from 'http' import * as httpClient from '@actions/http-client' import {OctokitOptions} from '@octokit/core/dist-types/types' -/** - * Disambiguates the constructor overload parameters - */ -export function disambiguate( - token: string | OctokitOptions, - opts?: OctokitOptions -): [string, OctokitOptions] { - return [ - typeof token === 'string' ? token : '', - typeof token === 'object' ? token : opts || {} - ] -} - -export function getOctokitOptions( - args: [string, OctokitOptions] -): OctokitOptions { - const token = args[0] - const options = {...args[1]} // Shallow clone - don't mutate the object provided by the caller - - // Auth - const auth = getAuthString(token, options) - if (auth) { - options.auth = auth - } - - return options -} - export function getAuthString( token: string, options: OctokitOptions From 1d6349424934b90266de62ed690879d554d78689 Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Wed, 20 May 2020 14:12:17 -0400 Subject: [PATCH 07/11] Minor cleanup --- packages/github/README.md | 11 +++++++---- packages/github/src/github.ts | 2 +- packages/github/src/internal/utils.ts | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/github/README.md b/packages/github/README.md index 32c832ea8f..ecf56cd043 100644 --- a/packages/github/README.md +++ b/packages/github/README.md @@ -18,8 +18,13 @@ async function run() { const myToken = core.getInput('myToken'); const octokit = new github.GitHub(github.getOptions(myToken)); - // or you may set the authentication on the options yourself - // const octokit = new github.GitHub({auth: `token ${myToken}`}); + + // You can set the authentication on the options yourself instead + // const octokit = new github.GitHub({auth: `token ${myToken}`, userAgent: "MyActionVersion1"}); + + // You can also pass in additional options as a second parameter to getOptions + // const octokit = new github.GitHub(github.getOptions(myToken), {userAgent: "MyActionVersion1"}); + const { data: pullRequest } = await octokit.pulls.get({ owner: 'octokit', repo: 'rest.js', @@ -35,8 +40,6 @@ async function run() { run(); ``` -You can pass client options, as specified by [Octokit](https://github.com/octokit/core.js#options), as a second argument getOptions function. - You can also make GraphQL requests. See https://github.com/octokit/graphql.js for the API. ```js diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index 4008a8690c..bd97ad1c8f 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -23,7 +23,7 @@ export const GitHub = Octokit.plugin( ).defaults(defaults) /** - * Convience function to correctly format options from a token + * Convience function to correctly format Octokit Options to pass into the constructor. * * @param token the repo PAT or GITHUB_TOKEN * @param options other options to set diff --git a/packages/github/src/internal/utils.ts b/packages/github/src/internal/utils.ts index 7c647a69ef..ea5ec382fe 100644 --- a/packages/github/src/internal/utils.ts +++ b/packages/github/src/internal/utils.ts @@ -15,7 +15,7 @@ export function getAuthString( return typeof options.auth === 'string' ? options.auth : `token ${token}` } -export function getProxyAgent(destinationUrl: string): http.Agent | undefined { +export function getProxyAgent(destinationUrl: string): http.Agent { const hc = new httpClient.HttpClient() return hc.getAgent(destinationUrl) } From c0f321ee4fe4cc46534b7f5ec54608b6815281b9 Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Fri, 22 May 2020 16:24:25 -0400 Subject: [PATCH 08/11] Make mainline path getOctokit function --- packages/github/README.md | 30 ++++++++++++++++--- .../github/__tests__/github.proxy.test.ts | 18 +++++------ packages/github/__tests__/github.test.ts | 23 +++++++++++--- packages/github/src/github.ts | 9 +++++- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/packages/github/README.md b/packages/github/README.md index ecf56cd043..8818555ca0 100644 --- a/packages/github/README.md +++ b/packages/github/README.md @@ -17,14 +17,14 @@ async function run() { // https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#about-the-github_token-secret const myToken = core.getInput('myToken'); - const octokit = new github.GitHub(github.getOptions(myToken)); + const octokit = github.getOctokit(token) + + // You can also pass in additional options as a second parameter to getOptions + // const octokit = github.getOctokit(myToken, {userAgent: "MyActionVersion1"}); // You can set the authentication on the options yourself instead // const octokit = new github.GitHub({auth: `token ${myToken}`, userAgent: "MyActionVersion1"}); - // You can also pass in additional options as a second parameter to getOptions - // const octokit = new github.GitHub(github.getOptions(myToken), {userAgent: "MyActionVersion1"}); - const { data: pullRequest } = await octokit.pulls.get({ owner: 'octokit', repo: 'rest.js', @@ -76,3 +76,25 @@ if (github.context.eventName === 'push') { core.info(`The head commit is: ${pushPayload.head}`) } ``` + +## Extending the Octokit instance +`@octokit/core` now supports the [plugin architecture](https://github.com/octokit/core.js#plugins). You can extend the GitHub instance using plugins. + +For example, using the `@octokit/plugin-enterprise-server` you can now access enterprise admin apis on GHES instances. + +```ts +const { GitHub, getOptions } = require("@actions/github"); +const { enterpriseServer220Admin } = require("@octokit/plugin-enterprise-server"); + +const octokit = GitHub.plugin(enterpriseServer220Admin).defaults({userAgent: "MyNewUserAgent"}) +// or override some of the default values as well +// const octokit = GitHub.plugin(enterpriseServer220Admin).defaults({userAgent: "MyNewUserAgent"}) + +const myToken = core.getInput('myToken'); +const myOctokit = new octokit(getOptions(token)) +// Create a new user +myOctokit.enterpriseAdmin.createUser({ + username: "testuser", + email: "testuser@test.com", +}); +``` diff --git a/packages/github/__tests__/github.proxy.test.ts b/packages/github/__tests__/github.proxy.test.ts index 521f1bfc96..5da06582cd 100644 --- a/packages/github/__tests__/github.proxy.test.ts +++ b/packages/github/__tests__/github.proxy.test.ts @@ -7,7 +7,7 @@ const proxyUrl = 'http://127.0.0.1:8081' const originalProxyUrl = process.env['https_proxy'] process.env['https_proxy'] = proxyUrl // eslint-disable-next-line import/first -import {GitHub, getOptions} from '../src/github' +import {getOctokit} from '../src/github' describe('@actions/github', () => { let proxyConnects: string[] @@ -48,7 +48,7 @@ describe('@actions/github', () => { return } - const octokit = new GitHub(getOptions(token)) + const octokit = getOctokit(token) const branch = await octokit.repos.getBranch({ owner: 'actions', repo: 'toolkit', @@ -64,7 +64,7 @@ describe('@actions/github', () => { return } process.env['https_proxy'] = proxyUrl - const octokit = new GitHub(getOptions(token)) + const octokit = getOctokit(token) const repository = await octokit.graphql( '{repository(owner:"actions", name:"toolkit"){name}}' @@ -80,13 +80,11 @@ describe('@actions/github', () => { } // Valid token - const octokit = new GitHub( - getOptions(token, { - request: { - agent: new https.Agent() - } - }) - ) + const octokit = getOctokit(token, { + request: { + agent: new https.Agent() + } + }) const branch = await octokit.repos.getBranch({ owner: 'actions', repo: 'toolkit', diff --git a/packages/github/__tests__/github.test.ts b/packages/github/__tests__/github.test.ts index 755616ca8a..917c35055e 100644 --- a/packages/github/__tests__/github.test.ts +++ b/packages/github/__tests__/github.test.ts @@ -1,6 +1,6 @@ import * as http from 'http' import proxy from 'proxy' -import {GitHub, getOptions} from '../src/github' +import {GitHub, getOctokitOptions, getOctokit} from '../src/github' describe('@actions/github', () => { const proxyUrl = 'http://127.0.0.1:8080' @@ -43,7 +43,22 @@ describe('@actions/github', () => { if (!token) { return } - const octokit = new GitHub(getOptions(token)) + const octokit = new GitHub(getOctokitOptions(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 getOctokit client', async () => { + const token = getToken() + if (!token) { + return + } + const octokit = getOctokit(token) const branch = await octokit.repos.getBranch({ owner: 'actions', repo: 'toolkit', @@ -90,7 +105,7 @@ describe('@actions/github', () => { return } - const octokit = new GitHub(getOptions(token)) + const octokit = getOctokit(token) const repository = await octokit.graphql( '{repository(owner:"actions", name:"toolkit"){name}}' ) @@ -105,7 +120,7 @@ describe('@actions/github', () => { } // Valid token - let octokit = new GitHub(getOptions(token)) + let octokit = getOctokit(token) const repository = await octokit.graphql( '{repository(owner:"actions", name:"toolkit"){name}}' ) diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index bd97ad1c8f..5af3e081c1 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -28,7 +28,7 @@ export const GitHub = Octokit.plugin( * @param token the repo PAT or GITHUB_TOKEN * @param options other options to set */ -export function getOptions( +export function getOctokitOptions( token: string, options?: OctokitOptions ): OctokitOptions { @@ -42,3 +42,10 @@ export function getOptions( return opts } + +export function getOctokit( + token: string, + options?: OctokitOptions +): InstanceType { + return new GitHub(getOctokitOptions(token, options)) +} From 309c5a626dfcaec7defd0d1583f741caaa0db8f7 Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Wed, 27 May 2020 13:43:52 -0400 Subject: [PATCH 09/11] move non mainline scenarios to helper functions --- packages/github/README.md | 9 ++--- packages/github/__tests__/github.test.ts | 3 +- packages/github/src/github.ts | 35 ++----------------- packages/github/src/utils.ts | 44 ++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 40 deletions(-) create mode 100644 packages/github/src/utils.ts diff --git a/packages/github/README.md b/packages/github/README.md index 8818555ca0..b8565baf56 100644 --- a/packages/github/README.md +++ b/packages/github/README.md @@ -22,9 +22,6 @@ async function run() { // You can also pass in additional options as a second parameter to getOptions // const octokit = github.getOctokit(myToken, {userAgent: "MyActionVersion1"}); - // You can set the authentication on the options yourself instead - // const octokit = new github.GitHub({auth: `token ${myToken}`, userAgent: "MyActionVersion1"}); - const { data: pullRequest } = await octokit.pulls.get({ owner: 'octokit', repo: 'rest.js', @@ -83,10 +80,10 @@ if (github.context.eventName === 'push') { For example, using the `@octokit/plugin-enterprise-server` you can now access enterprise admin apis on GHES instances. ```ts -const { GitHub, getOptions } = require("@actions/github"); -const { enterpriseServer220Admin } = require("@octokit/plugin-enterprise-server"); +import { GitHub, getOptions } from '@actions/github/utils' +import { enterpriseServer220Admin } from '@octokit/plugin-enterprise-server' -const octokit = GitHub.plugin(enterpriseServer220Admin).defaults({userAgent: "MyNewUserAgent"}) +const octokit = GitHub.plugin(enterpriseServer220Admin) // or override some of the default values as well // const octokit = GitHub.plugin(enterpriseServer220Admin).defaults({userAgent: "MyNewUserAgent"}) diff --git a/packages/github/__tests__/github.test.ts b/packages/github/__tests__/github.test.ts index 917c35055e..4e02c7b316 100644 --- a/packages/github/__tests__/github.test.ts +++ b/packages/github/__tests__/github.test.ts @@ -1,6 +1,7 @@ import * as http from 'http' import proxy from 'proxy' -import {GitHub, getOctokitOptions, getOctokit} from '../src/github' +import {getOctokit} from '../src/github' +import {GitHub, getOctokitOptions} from '../src/utils' describe('@actions/github', () => { const proxyUrl = 'http://127.0.0.1:8080' diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts index 5af3e081c1..bada7e522d 100644 --- a/packages/github/src/github.ts +++ b/packages/github/src/github.ts @@ -1,48 +1,17 @@ import * as Context from './context' -import * as Utils from './internal/utils' +import {GitHub, getOctokitOptions} from './utils' // octokit + plugins -import {Octokit} from '@octokit/core' import {OctokitOptions} from '@octokit/core/dist-types/types' -import {restEndpointMethods} from '@octokit/plugin-rest-endpoint-methods' -import {paginateRest} from '@octokit/plugin-paginate-rest' export const context = new Context.Context() -const baseUrl = Utils.getApiBaseUrl() -const defaults = { - baseUrl, - request: { - agent: Utils.getProxyAgent(baseUrl) - } -} - -export const GitHub = Octokit.plugin( - restEndpointMethods, - paginateRest -).defaults(defaults) - /** - * Convience function to correctly format Octokit Options to pass into the constructor. + * Returns a hydrated octokit ready to use for GitHub Actions * * @param token the repo PAT or GITHUB_TOKEN * @param options other options to set */ -export function getOctokitOptions( - token: string, - options?: OctokitOptions -): OctokitOptions { - const opts = Object.assign({}, options || {}) // Shallow clone - don't mutate the object provided by the caller - - // Auth - const auth = Utils.getAuthString(token, opts) - if (auth) { - opts.auth = auth - } - - return opts -} - export function getOctokit( token: string, options?: OctokitOptions diff --git a/packages/github/src/utils.ts b/packages/github/src/utils.ts new file mode 100644 index 0000000000..bbc71c10fe --- /dev/null +++ b/packages/github/src/utils.ts @@ -0,0 +1,44 @@ +import * as Context from './context' +import * as Utils from './internal/utils' + +// octokit + plugins +import {Octokit} from '@octokit/core' +import {OctokitOptions} from '@octokit/core/dist-types/types' +import {restEndpointMethods} from '@octokit/plugin-rest-endpoint-methods' +import {paginateRest} from '@octokit/plugin-paginate-rest' + +export const context = new Context.Context() + +const baseUrl = Utils.getApiBaseUrl() +const defaults = { + baseUrl, + request: { + agent: Utils.getProxyAgent(baseUrl) + } +} + +export const GitHub = Octokit.plugin( + restEndpointMethods, + paginateRest +).defaults(defaults) + +/** + * Convience function to correctly format Octokit Options to pass into the constructor. + * + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set + */ +export function getOctokitOptions( + token: string, + options?: OctokitOptions +): OctokitOptions { + const opts = Object.assign({}, options || {}) // Shallow clone - don't mutate the object provided by the caller + + // Auth + const auth = Utils.getAuthString(token, opts) + if (auth) { + opts.auth = auth + } + + return opts +} From ebb9e5222fb39a56c023223ec2cbb8b501da14ce Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Tue, 2 Jun 2020 20:24:04 -0400 Subject: [PATCH 10/11] Cleanup docs --- packages/github/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/github/README.md b/packages/github/README.md index b8565baf56..f0153d2bae 100644 --- a/packages/github/README.md +++ b/packages/github/README.md @@ -19,7 +19,7 @@ async function run() { const octokit = github.getOctokit(token) - // You can also pass in additional options as a second parameter to getOptions + // You can also pass in additional options as a second parameter to getOctokit // const octokit = github.getOctokit(myToken, {userAgent: "MyActionVersion1"}); const { data: pullRequest } = await octokit.pulls.get({ @@ -80,7 +80,7 @@ if (github.context.eventName === 'push') { For example, using the `@octokit/plugin-enterprise-server` you can now access enterprise admin apis on GHES instances. ```ts -import { GitHub, getOptions } from '@actions/github/utils' +import { GitHub, getOctokitOptions } from '@actions/github/lib/utils' import { enterpriseServer220Admin } from '@octokit/plugin-enterprise-server' const octokit = GitHub.plugin(enterpriseServer220Admin) @@ -88,7 +88,7 @@ const octokit = GitHub.plugin(enterpriseServer220Admin) // const octokit = GitHub.plugin(enterpriseServer220Admin).defaults({userAgent: "MyNewUserAgent"}) const myToken = core.getInput('myToken'); -const myOctokit = new octokit(getOptions(token)) +const myOctokit = new octokit(getOctokitOptions(token)) // Create a new user myOctokit.enterpriseAdmin.createUser({ username: "testuser", From eb77465f24247c2af364695c80874bdf3a44db65 Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Tue, 2 Jun 2020 21:34:27 -0400 Subject: [PATCH 11/11] minor doc update --- packages/github/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/github/README.md b/packages/github/README.md index f0153d2bae..eb034088d5 100644 --- a/packages/github/README.md +++ b/packages/github/README.md @@ -91,7 +91,7 @@ const myToken = core.getInput('myToken'); const myOctokit = new octokit(getOctokitOptions(token)) // Create a new user myOctokit.enterpriseAdmin.createUser({ - username: "testuser", + login: "testuser", email: "testuser@test.com", }); ```