mirror of
https://git.mirrors.martin98.com/https://github.com/actions/toolkit
synced 2026-04-03 23:13:15 +08:00
@actions/github v3 using Octokit/core (#453)
* Rebuild to use @Octokit/Core
This commit is contained in:
@@ -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))
|
||||
}
|
||||
|
||||
25
packages/github/src/internal/utils.ts
Normal file
25
packages/github/src/internal/utils.ts
Normal 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'
|
||||
}
|
||||
44
packages/github/src/utils.ts
Normal file
44
packages/github/src/utils.ts
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user