@actions/github v3 using Octokit/core (#453)

* Rebuild to use @Octokit/Core
This commit is contained in:
Thomas Boop
2020-06-02 21:39:46 -04:00
committed by GitHub
parent 9ba7c679ad
commit 4a89cf72de
8 changed files with 311 additions and 319 deletions

View File

@@ -1,158 +1,20 @@
// Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/github.ts
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 {Octokit} from '@octokit/rest'
import * as Context from './context'
import * as http from 'http'
import * as httpClient from '@actions/http-client'
import {GitHub, getOctokitOptions} from './utils'
// We need this in order to extend Octokit
Octokit.prototype = new Octokit()
// octokit + plugins
import {OctokitOptions} from '@octokit/core/dist-types/types'
export const context = new Context.Context()
export class GitHub extends Octokit {
graphql: GraphQL
/* 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<Octokit.Options, 'auth'>)
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
// 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, Octokit.Options]): 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: 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(
destinationUrl: string,
options: Octokit.Options
): http.Agent | undefined {
if (!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
}
/**
* 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 getOctokit(
token: string,
options?: OctokitOptions
): InstanceType<typeof GitHub> {
return new GitHub(getOctokitOptions(token, options))
}

View File

@@ -0,0 +1,25 @@
import * as http from 'http'
import * as httpClient from '@actions/http-client'
import {OctokitOptions} from '@octokit/core/dist-types/types'
export function getAuthString(
token: string,
options: OctokitOptions
): string | undefined {
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): http.Agent {
const hc = new httpClient.HttpClient()
return hc.getAgent(destinationUrl)
}
export function getApiBaseUrl(): string {
return process.env['GITHUB_API_URL'] || 'https://api.github.com'
}

View File

@@ -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
}