Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@actions/github v3 using Octokit/core #453

Merged
merged 11 commits into from Jun 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 27 additions & 4 deletions packages/github/README.md
Expand Up @@ -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');
Expand All @@ -17,7 +17,10 @@ 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 = github.getOctokit(token)

// 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({
owner: 'octokit',
Expand All @@ -34,8 +37,6 @@ 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 also make GraphQL requests. See https://github.com/octokit/graphql.js for the API.

```js
Expand Down Expand Up @@ -72,3 +73,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
import { GitHub, getOctokitOptions } from '@actions/github/lib/utils'
import { enterpriseServer220Admin } from '@octokit/plugin-enterprise-server'

const octokit = GitHub.plugin(enterpriseServer220Admin)
// 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(getOctokitOptions(token))
// Create a new user
myOctokit.enterpriseAdmin.createUser({
login: "testuser",
email: "testuser@test.com",
});
```
109 changes: 109 additions & 0 deletions packages/github/__tests__/github.proxy.test.ts
@@ -0,0 +1,109 @@
import * as http from 'http'
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now load proxy settings when the module is imported because of the way defaults works. This required a new test suite for proxy tests.

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 {getOctokit} 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 = getOctokit(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 = getOctokit(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 = getOctokit(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
}
})
55 changes: 19 additions & 36 deletions packages/github/__tests__/github.test.ts
@@ -1,6 +1,7 @@
import * as http from 'http'
import proxy from 'proxy'
import {GitHub} 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'
Expand Down Expand Up @@ -43,8 +44,22 @@ describe('@actions/github', () => {
if (!token) {
return
}
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)
})

const octokit = new GitHub(token)
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',
Expand Down Expand Up @@ -85,30 +100,13 @@ describe('@actions/github', () => {
expect(failed).toBeTruthy()
})

it('basic REST client with proxy', async () => {
thboop marked this conversation as resolved.
Show resolved Hide resolved
const token = getToken()
if (!token) {
return
}

process.env['https_proxy'] = proxyUrl
const octokit = new GitHub(token)
const branch = await octokit.repos.getBranch({
owner: 'actions',
repo: 'toolkit',
branch: 'master'
})
expect(branch.data.name).toBe('master')
expect(proxyConnects).toEqual(['api.github.com:443'])
})

it('basic GraphQL client', async () => {
const token = getToken()
if (!token) {
return
}

const octokit = new GitHub(token)
const octokit = getOctokit(token)
const repository = await octokit.graphql(
'{repository(owner:"actions", name:"toolkit"){name}}'
)
Expand All @@ -123,7 +121,7 @@ describe('@actions/github', () => {
}

// Valid token
let octokit = new GitHub(token)
let octokit = getOctokit(token)
const repository = await octokit.graphql(
'{repository(owner:"actions", name:"toolkit"){name}}'
)
Expand All @@ -143,21 +141,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'])
})

function getToken(): string {
const token = process.env['GITHUB_TOKEN'] || ''
if (!token && first) {
Expand Down