1
0
Fork 0

Add github package (#32)

* Add github package

* Docs

* Feedback

* Accidentally added extra

* Allow octokit to be extended

* Respond to feedback

* Feedback
pull/35/head
Danny McCormick 2019-07-29 13:09:32 -04:00 committed by GitHub
parent 4f5cf60872
commit 2a2b51f939
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 5617 additions and 0 deletions

47
packages/github/README.md Normal file
View File

@ -0,0 +1,47 @@
# `@actions/github`
> A hydrated Octokit client.
## Usage
Returns an [Octokit SDK] client. See https://octokit.github.io/rest.js for the API.
```
const github = require('@actions/github');
// This should be a token with access to your repository scoped in as a secret.
const myToken = process.env.GITHUB_TOKEN
const octokit = new github.GitHub(myToken)
const pulls = await octokit.pulls.get({
owner: 'octokit',
repo: 'rest.js',
pull_number: 123,
mediaType: {
format: 'diff'
}
})
console.log(pulls)
```
You can also make GraphQL requests:
```
const result = await octokit.graphql(query, variables)
```
Finally, you can get the context of the current action:
```
const github = require('@actions/github');
const context = github.context
const newIssue = await octokit.issues.create({
...context.repo,
title: 'New issue!',
body: 'Hello Universe!'
})
```

View File

@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`@actions/context return error for context.repo when repository doesn't exist 1`] = `"context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"`;

View File

@ -0,0 +1,80 @@
import * as path from 'path'
import {Context} from '../src/context'
/* eslint-disable @typescript-eslint/no-require-imports */
describe('@actions/context', () => {
let context: Context
beforeEach(() => {
process.env.GITHUB_EVENT_PATH = path.join(__dirname, 'payload.json')
process.env.GITHUB_REPOSITORY = 'actions/toolkit'
context = new Context()
})
it('returns the payload object', () => {
expect(context.payload).toEqual(require('./payload.json'))
})
it('returns an empty payload if the GITHUB_EVENT_PATH environment variable is falsey', () => {
delete process.env.GITHUB_EVENT_PATH
context = new Context()
expect(context.payload).toEqual({})
})
it('returns attributes from the GITHUB_REPOSITORY', () => {
expect(context.repo).toEqual({owner: 'actions', repo: 'toolkit'})
})
it('returns attributes from the repository payload', () => {
delete process.env.GITHUB_REPOSITORY
context.payload.repository = {
name: 'test',
owner: {login: 'user'}
}
expect(context.repo).toEqual({owner: 'user', repo: 'test'})
})
it("return error for context.repo when repository doesn't exist", () => {
delete process.env.GITHUB_REPOSITORY
context.payload.repository = undefined
expect(() => context.repo).toThrowErrorMatchingSnapshot()
})
it('returns issue attributes from the repository', () => {
expect(context.issue).toEqual({
owner: 'actions',
repo: 'toolkit',
number: 1
})
})
it('works with pullRequest payloads', () => {
delete process.env.GITHUB_REPOSITORY
context.payload = {
pullRequest: {number: 2},
repository: {owner: {login: 'user'}, name: 'test'}
}
expect(context.issue).toEqual({
number: 2,
owner: 'user',
repo: 'test'
})
})
it('works with payload.number payloads', () => {
delete process.env.GITHUB_REPOSITORY
context.payload = {
number: 2,
repository: {owner: {login: 'user'}, name: 'test'}
}
expect(context.issue).toEqual({
number: 2,
owner: 'user',
repo: 'test'
})
})
})

View File

@ -0,0 +1,15 @@
{
"action": "opened",
"repository": {
"owner": {
"login": "user"
},
"name": "test"
},
"issue": {
"number": 1
},
"sender": {
"type": "User"
}
}

View File

@ -0,0 +1,11 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true
}

5250
packages/github/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
{
"name": "@actions/github",
"version": "0.0.0",
"description": "Actions github lib",
"keywords": [
"github",
"actions"
],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/github",
"license": "MIT",
"main": "lib/github.js",
"directories": {
"lib": "lib",
"test": "__tests__"
},
"files": [
"lib"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/actions/toolkit.git"
},
"scripts": {
"test": "jest",
"build": "tsc",
"tsc": "tsc"
},
"bugs": {
"url": "https://github.com/actions/toolkit/issues"
},
"dependencies": {
"@octokit/graphql": "^2.0.1",
"@octokit/rest": "^16.15.0"
},
"devDependencies": {
"jest": "^24.7.1"
}
}

View File

@ -0,0 +1,36 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
declare module '@octokit/graphql' {
export interface GraphQlQueryResponse {
data: {[key: string]: any} | null
errors?: [
{
message: string
path: [string]
extensions: {[key: string]: any}
locations: [
{
line: number
column: number
}
]
}
]
}
export interface GraphQLError {
message: string
locations?: {line: number; column: number}[]
path?: (string | number)[]
extensions?: {
[key: string]: any
}
}
export interface Variables {
[key: string]: any
}
export function defaults(
options: any
): (query: string, variables?: Variables) => Promise<GraphQlQueryResponse>
}

View File

@ -0,0 +1,60 @@
// Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/context.ts
import {WebhookPayload} from './interfaces'
/* eslint-disable @typescript-eslint/no-require-imports */
export class Context {
/**
* Webhook payload object that triggered the workflow
*/
payload: WebhookPayload
eventName: string
sha: string
ref: string
workflow: string
action: string
actor: string
/**
* Hydrate the context from the environment
*/
constructor() {
this.payload = process.env.GITHUB_EVENT_PATH
? require(process.env.GITHUB_EVENT_PATH)
: {}
this.eventName = process.env.GITHUB_EVENT_NAME as string
this.sha = process.env.GITHUB_SHA as string
this.ref = process.env.GITHUB_REF as string
this.workflow = process.env.GITHUB_WORKFLOW as string
this.action = process.env.GITHUB_ACTION as string
this.actor = process.env.GITHUB_ACTOR as string
}
get issue(): {owner: string; repo: string; number: number} {
const payload = this.payload
return {
...this.repo,
number: (payload.issue || payload.pullRequest || payload).number
}
}
get repo(): {owner: string; repo: string} {
if (process.env.GITHUB_REPOSITORY) {
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/')
return {owner, repo}
}
if (this.payload.repository) {
return {
owner: this.payload.repository.owner.login,
repo: this.payload.repository.name
}
}
throw new Error(
"context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"
)
}
}

View File

@ -0,0 +1,23 @@
// Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/github.ts
import {GraphQlQueryResponse, Variables, defaults} from '@octokit/graphql'
import Octokit from '@octokit/rest'
import * as Context from './context'
// We need this in order to extend Octokit
Octokit.prototype = new Octokit()
module.exports.context = new Context.Context()
export class GitHub extends Octokit {
graphql: (
query: string,
variables?: Variables
) => Promise<GraphQlQueryResponse>
constructor(token: string) {
super({auth: `token ${token}`})
this.graphql = defaults({
headers: {authorization: `token ${token}`}
})
}
}

View File

@ -0,0 +1,39 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
export interface PayloadRepository {
[key: string]: any
fullName?: string
name: string
owner: {
[key: string]: any
login: string
name?: string
}
htmlUrl?: string
}
export interface WebhookPayload {
[key: string]: any
repository?: PayloadRepository
issue?: {
[key: string]: any
number: number
html_url?: string
body?: string
}
pullRequest?: {
[key: string]: any
number: number
htmlUrl?: string
body?: string
}
sender?: {
[key: string]: any
type: string
}
action?: string
installation?: {
id: number
[key: string]: any
}
}

View File

@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./",
"esModuleInterop": true,
"outDir": "./lib",
"rootDir": "./src"
},
"include": [
"./src"
]
}