mirror of
https://github.com/all-contributors/cli.git
synced 2025-01-09 13:36: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"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"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 -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
|
||||
- [ all-contributors-cli ](#all-contributors-cli)
|
||||
- [The problem](#the-problem)
|
||||
- [This solution](#this-solution)
|
||||
- [Using the all-contributors-cli](#using-the-all-contributors-cli)
|
||||
- [Contributors ✨](#contributors-)
|
||||
- [LICENSE](#license)
|
||||
- [The problem](#the-problem)
|
||||
- [This solution](#this-solution)
|
||||
- [Using the all-contributors-cli](#using-the-all-contributors-cli)
|
||||
- [Contributors ✨](#contributors-%e2%9c%a8)
|
||||
- [LICENSE](#license)
|
||||
|
||||
<!-- 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://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://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>
|
||||
</tr>
|
||||
</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 () => {
|
||||
nock('https://api.github.com')
|
||||
.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 () => {
|
||||
nock('http://api.github.myhost.com:3000')
|
||||
nock('http://github.myhost.com:3000/api/v3')
|
||||
.get('/users/nodisplayname')
|
||||
.reply(200, {
|
||||
login: 'nodisplayname',
|
||||
|
|
|
@ -1,6 +1,27 @@
|
|||
const url = require('url')
|
||||
const pify = require('pify')
|
||||
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 = '') {
|
||||
const requestHeaders = {
|
||||
'User-Agent': 'request',
|
||||
|
@ -27,10 +48,10 @@ function getNextLink(link) {
|
|||
return nextLink.split(';')[0].slice(1, -1)
|
||||
}
|
||||
|
||||
function getContributorsPage(url, optionalPrivateToken) {
|
||||
function getContributorsPage(githubUrl, optionalPrivateToken) {
|
||||
return request
|
||||
.get({
|
||||
url,
|
||||
url: githubUrl,
|
||||
headers: getRequestHeaders(optionalPrivateToken),
|
||||
})
|
||||
.then(res => {
|
||||
|
@ -55,18 +76,13 @@ function getContributorsPage(url, optionalPrivateToken) {
|
|||
}
|
||||
|
||||
const getUserInfo = function(username, hostname, optionalPrivateToken) {
|
||||
/* eslint-disable complexity */
|
||||
if (!hostname) {
|
||||
hostname = 'https://github.com'
|
||||
}
|
||||
|
||||
if (!username) {
|
||||
throw new Error(
|
||||
`No login when adding a contributor. Please specify a username.`,
|
||||
)
|
||||
}
|
||||
|
||||
const root = hostname.replace(/:\/\//, '://api.')
|
||||
const root = getApiHost(hostname)
|
||||
return request
|
||||
.get({
|
||||
url: `${root}/users/${username}`,
|
||||
|
@ -77,6 +93,16 @@ const getUserInfo = function(username, hostname, optionalPrivateToken) {
|
|||
|
||||
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...
|
||||
if (!profile && body.message) {
|
||||
throw new Error(
|
||||
|
@ -96,13 +122,9 @@ const getUserInfo = function(username, hostname, optionalPrivateToken) {
|
|||
}
|
||||
|
||||
const getContributors = function(owner, name, hostname, optionalPrivateToken) {
|
||||
if (!hostname) {
|
||||
hostname = 'https://github.com'
|
||||
}
|
||||
|
||||
const root = hostname.replace(/:\/\//, '://api.')
|
||||
const url = `${root}/repos/${owner}/${name}/contributors?per_page=100`
|
||||
return getContributorsPage(url, optionalPrivateToken)
|
||||
const root = getApiHost(hostname)
|
||||
const contributorsUrl = `${root}/repos/${owner}/${name}/contributors?per_page=100`
|
||||
return getContributorsPage(contributorsUrl, optionalPrivateToken)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
Loading…
Reference in a new issue