mirror of
https://github.com/all-contributors/cli.git
synced 2025-01-10 05:56:29 +00:00
feat: support Github Enterprise (#97)
* add isEnterprise config option and add function to change hostname if on enterprise * add hipstersmoothie as contributor * infer enterprise API * handle enterprise authentication * add tylerkrupicka as a contributor Co-authored-by: Tyler Krupicka <tylerkrupicka@gmail.com> Co-authored-by: Maximilian Berkmann <maxieberkmann@gmail.com>
This commit is contained in:
parent
4f407508cc
commit
0965095ecd
4 changed files with 69 additions and 22 deletions
|
@ -381,6 +381,16 @@
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"login": "tylerkrupicka",
|
||||||
|
"name": "Tyler Krupicka",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/5761061?s=460&v=4",
|
||||||
|
"profile": "https://github.com/tylerkrupicka",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"login": "smoia",
|
"login": "smoia",
|
||||||
"name": "Stefano Moia",
|
"name": "Stefano Moia",
|
||||||
|
|
12
README.md
12
README.md
|
@ -1,12 +1,11 @@
|
||||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||||
|
|
||||||
- [ all-contributors-cli ](#all-contributors-cli)
|
- [The problem](#the-problem)
|
||||||
- [The problem](#the-problem)
|
- [This solution](#this-solution)
|
||||||
- [This solution](#this-solution)
|
- [Using the all-contributors-cli](#using-the-all-contributors-cli)
|
||||||
- [Using the all-contributors-cli](#using-the-all-contributors-cli)
|
- [Contributors ✨](#contributors-%e2%9c%a8)
|
||||||
- [Contributors ✨](#contributors-)
|
- [LICENSE](#license)
|
||||||
- [LICENSE](#license)
|
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
|
||||||
|
@ -130,6 +129,7 @@ Thanks goes to these wonderful people
|
||||||
<td align="center"><a href="https://www.destro.me"><img src="https://avatars1.githubusercontent.com/u/7031675?v=4" width="100px;" alt=""/><br /><sub><b>Fabrizio</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/issues?q=author%3Adexpota" title="Bug reports">🐛</a> <a href="https://github.com/all-contributors/all-contributors-cli/commits?author=dexpota" title="Code">💻</a></td>
|
<td align="center"><a href="https://www.destro.me"><img src="https://avatars1.githubusercontent.com/u/7031675?v=4" width="100px;" alt=""/><br /><sub><b>Fabrizio</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/issues?q=author%3Adexpota" title="Bug reports">🐛</a> <a href="https://github.com/all-contributors/all-contributors-cli/commits?author=dexpota" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/marceloalves"><img src="https://avatars1.githubusercontent.com/u/216782?v=4" width="100px;" alt=""/><br /><sub><b>Marcelo Alves</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/commits?author=MarceloAlves" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/marceloalves"><img src="https://avatars1.githubusercontent.com/u/216782?v=4" width="100px;" alt=""/><br /><sub><b>Marcelo Alves</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/commits?author=MarceloAlves" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://phacks.dev/"><img src="https://avatars1.githubusercontent.com/u/2587348?v=4" width="100px;" alt=""/><br /><sub><b>Nicolas Goutay</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/commits?author=phacks" title="Code">💻</a></td>
|
<td align="center"><a href="https://phacks.dev/"><img src="https://avatars1.githubusercontent.com/u/2587348?v=4" width="100px;" alt=""/><br /><sub><b>Nicolas Goutay</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/commits?author=phacks" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/tylerkrupicka"><img src="https://avatars1.githubusercontent.com/u/5761061?s=460&v=4" width="100px;" alt=""/><br /><sub><b>Tyler Krupicka</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/commits?author=tylerkrupicka" title="Code">💻</a> <a href="https://github.com/all-contributors/all-contributors-cli/commits?author=tylerkrupicka" title="Tests">⚠️</a></td>
|
||||||
<td align="center"><a href="https://github.com/smoia"><img src="https://avatars3.githubusercontent.com/u/35300580?v=4" width="100px;" alt=""/><br /><sub><b>Stefano Moia</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/commits?author=smoia" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/smoia"><img src="https://avatars3.githubusercontent.com/u/35300580?v=4" width="100px;" alt=""/><br /><sub><b>Stefano Moia</b></sub></a><br /><a href="https://github.com/all-contributors/all-contributors-cli/commits?author=smoia" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -85,6 +85,21 @@ test('Throw error when non existent username is provided', async () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Throw error when missing enterprise authentication', async () => {
|
||||||
|
const username = 'notauthenticated'
|
||||||
|
nock('http://github.myhost.com:3000/api/v3')
|
||||||
|
.get(`/users/${username}`)
|
||||||
|
.reply(401, {
|
||||||
|
message: 'Must authenticate to access this API.',
|
||||||
|
documentation_url: 'https://developer.github.com/enterprise/2.17/v3',
|
||||||
|
})
|
||||||
|
await expect(
|
||||||
|
getUserInfo(username, 'http://github.myhost.com:3000'),
|
||||||
|
).rejects.toThrow(
|
||||||
|
`Missing authentication for GitHub API. Did you set PRIVATE_TOKEN?`,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
test('handle github errors', async () => {
|
test('handle github errors', async () => {
|
||||||
nock('https://api.github.com')
|
nock('https://api.github.com')
|
||||||
.get('/users/nodisplayname')
|
.get('/users/nodisplayname')
|
||||||
|
@ -174,7 +189,7 @@ test('append http when no absolute link is provided', async () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('retrieve user from a different github registry', async () => {
|
test('retrieve user from a different github registry', async () => {
|
||||||
nock('http://api.github.myhost.com:3000')
|
nock('http://github.myhost.com:3000/api/v3')
|
||||||
.get('/users/nodisplayname')
|
.get('/users/nodisplayname')
|
||||||
.reply(200, {
|
.reply(200, {
|
||||||
login: 'nodisplayname',
|
login: 'nodisplayname',
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
|
const url = require('url')
|
||||||
const pify = require('pify')
|
const pify = require('pify')
|
||||||
const request = pify(require('request'))
|
const request = pify(require('request'))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the host based on public or enterprise GitHub.
|
||||||
|
* https://developer.github.com/enterprise/2.17/v3/#current-version
|
||||||
|
*
|
||||||
|
* @param {String} hostname - Hostname from config.
|
||||||
|
* @returns {String} - Host for GitHub API.
|
||||||
|
*/
|
||||||
|
function getApiHost(hostname) {
|
||||||
|
if (!hostname) {
|
||||||
|
hostname = 'https://github.com'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostname !== 'https://github.com') {
|
||||||
|
// Assume Github Enterprise
|
||||||
|
return url.resolve(hostname, '/api/v3')
|
||||||
|
}
|
||||||
|
|
||||||
|
return hostname.replace(/:\/\//, '://api.')
|
||||||
|
}
|
||||||
|
|
||||||
function getRequestHeaders(optionalPrivateToken = '') {
|
function getRequestHeaders(optionalPrivateToken = '') {
|
||||||
const requestHeaders = {
|
const requestHeaders = {
|
||||||
'User-Agent': 'request',
|
'User-Agent': 'request',
|
||||||
|
@ -27,10 +48,10 @@ function getNextLink(link) {
|
||||||
return nextLink.split(';')[0].slice(1, -1)
|
return nextLink.split(';')[0].slice(1, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContributorsPage(url, optionalPrivateToken) {
|
function getContributorsPage(githubUrl, optionalPrivateToken) {
|
||||||
return request
|
return request
|
||||||
.get({
|
.get({
|
||||||
url,
|
url: githubUrl,
|
||||||
headers: getRequestHeaders(optionalPrivateToken),
|
headers: getRequestHeaders(optionalPrivateToken),
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
|
@ -55,18 +76,13 @@ function getContributorsPage(url, optionalPrivateToken) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserInfo = function(username, hostname, optionalPrivateToken) {
|
const getUserInfo = function(username, hostname, optionalPrivateToken) {
|
||||||
/* eslint-disable complexity */
|
|
||||||
if (!hostname) {
|
|
||||||
hostname = 'https://github.com'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!username) {
|
if (!username) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`No login when adding a contributor. Please specify a username.`,
|
`No login when adding a contributor. Please specify a username.`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const root = hostname.replace(/:\/\//, '://api.')
|
const root = getApiHost(hostname)
|
||||||
return request
|
return request
|
||||||
.get({
|
.get({
|
||||||
url: `${root}/users/${username}`,
|
url: `${root}/users/${username}`,
|
||||||
|
@ -77,6 +93,16 @@ const getUserInfo = function(username, hostname, optionalPrivateToken) {
|
||||||
|
|
||||||
let profile = body.blog || body.html_url
|
let profile = body.blog || body.html_url
|
||||||
|
|
||||||
|
// Check for authentication required
|
||||||
|
if (
|
||||||
|
(!profile && body.message.includes('Must authenticate')) ||
|
||||||
|
res.statusCode === 401
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Missing authentication for GitHub API. Did you set PRIVATE_TOKEN?`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Github throwing specific errors as 200...
|
// Github throwing specific errors as 200...
|
||||||
if (!profile && body.message) {
|
if (!profile && body.message) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -96,13 +122,9 @@ const getUserInfo = function(username, hostname, optionalPrivateToken) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getContributors = function(owner, name, hostname, optionalPrivateToken) {
|
const getContributors = function(owner, name, hostname, optionalPrivateToken) {
|
||||||
if (!hostname) {
|
const root = getApiHost(hostname)
|
||||||
hostname = 'https://github.com'
|
const contributorsUrl = `${root}/repos/${owner}/${name}/contributors?per_page=100`
|
||||||
}
|
return getContributorsPage(contributorsUrl, optionalPrivateToken)
|
||||||
|
|
||||||
const root = hostname.replace(/:\/\//, '://api.')
|
|
||||||
const url = `${root}/repos/${owner}/${name}/contributors?per_page=100`
|
|
||||||
return getContributorsPage(url, optionalPrivateToken)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
Loading…
Reference in a new issue