-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add API-based support for [GitLab] badges, add new GitLab Tag badge (#…
…6988) * Added GitLab Tag service * Added prettyMessage for when repo has no tags * Added pretty message for repo not found * core: esm-ify gitlab tag service * feat: support gitlab auth * feat: support custom gitlab url on tag badges * tests: add auth test for gitlab * docs: fix gitlab config key references * feat: support gitlab tag sorting options * docs: add custom gitlab instance example for tags badge * use v in gitlab route * fix: gitlab tag examples Co-authored-by: Ideotec <[email protected]> Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
- Loading branch information
1 parent
6bb62e4
commit 961e13b
Showing
10 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { BaseJsonService } from '../index.js' | ||
|
||
export default class GitLabBase extends BaseJsonService { | ||
static auth = { | ||
passKey: 'gitlab_token', | ||
serviceKey: 'gitlab', | ||
} | ||
|
||
async fetch({ url, options, schema, errorMessages }) { | ||
return this._requestJson( | ||
this.authHelper.withBasicAuth({ | ||
schema, | ||
url, | ||
options, | ||
errorMessages, | ||
}) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import Joi from 'joi' | ||
import { version as versionColor } from '../color-formatters.js' | ||
import { optionalUrl } from '../validators.js' | ||
import { latest } from '../version.js' | ||
import { addv } from '../text-formatters.js' | ||
import { NotFound } from '../index.js' | ||
import GitLabBase from './gitlab-base.js' | ||
|
||
const schema = Joi.array().items( | ||
Joi.object({ | ||
name: Joi.string().required(), | ||
}) | ||
) | ||
|
||
const queryParamSchema = Joi.object({ | ||
gitlab_url: optionalUrl, | ||
include_prereleases: Joi.equal(''), | ||
sort: Joi.string().valid('date', 'semver').default('date'), | ||
}).required() | ||
|
||
export default class GitlabTag extends GitLabBase { | ||
static category = 'version' | ||
|
||
static route = { | ||
base: 'gitlab/v/tag', | ||
pattern: ':user/:repo', | ||
queryParamSchema, | ||
} | ||
|
||
static examples = [ | ||
{ | ||
title: 'GitLab tag (latest by date)', | ||
namedParams: { | ||
user: 'shields-ops-group', | ||
repo: 'tag-test', | ||
}, | ||
queryParams: { sort: 'date' }, | ||
staticPreview: this.render({ version: 'v2.0.0' }), | ||
}, | ||
{ | ||
title: 'GitLab tag (latest by SemVer)', | ||
namedParams: { | ||
user: 'shields-ops-group', | ||
repo: 'tag-test', | ||
}, | ||
queryParams: { sort: 'semver' }, | ||
staticPreview: this.render({ version: 'v4.0.0' }), | ||
}, | ||
{ | ||
title: 'GitLab tag (latest by SemVer pre-release)', | ||
namedParams: { | ||
user: 'shields-ops-group', | ||
repo: 'tag-test', | ||
}, | ||
queryParams: { | ||
sort: 'semver', | ||
include_prereleases: null, | ||
}, | ||
staticPreview: this.render({ version: 'v5.0.0-beta.1', sort: 'semver' }), | ||
}, | ||
{ | ||
title: 'GitLab tag (custom instance)', | ||
namedParams: { | ||
user: 'GNOME', | ||
repo: 'librsvg', | ||
}, | ||
queryParams: { | ||
sort: 'semver', | ||
include_prereleases: null, | ||
gitlab_url: 'https://gitlab.gnome.org', | ||
}, | ||
staticPreview: this.render({ version: 'v2.51.4' }), | ||
}, | ||
] | ||
|
||
static defaultBadgeData = { label: 'tag' } | ||
|
||
static render({ version, sort }) { | ||
return { | ||
message: addv(version), | ||
color: sort === 'semver' ? versionColor(version) : 'blue', | ||
} | ||
} | ||
|
||
async fetch({ user, repo, baseUrl }) { | ||
// https://docs.gitlab.com/ee/api/tags.html | ||
// N.B. the documentation has contradictory information about default sort order. | ||
// As of 2020-10-11 the default is by date, but we add the `order_by` query param | ||
// explicitly in case that changes upstream. | ||
return super.fetch({ | ||
schema, | ||
url: `${baseUrl}/api/v4/projects/${user}%2F${repo}/repository/tags`, | ||
options: { qs: { order_by: 'updated' } }, | ||
errorMessages: { | ||
404: 'repo not found', | ||
}, | ||
}) | ||
} | ||
|
||
static transform({ tags, sort, includePrereleases }) { | ||
if (tags.length === 0) { | ||
throw new NotFound({ prettyMessage: 'no tags found' }) | ||
} | ||
|
||
if (sort === 'date') { | ||
return tags[0].name | ||
} | ||
|
||
return latest( | ||
tags.map(t => t.name), | ||
{ pre: includePrereleases } | ||
) | ||
} | ||
|
||
async handle( | ||
{ user, repo }, | ||
{ | ||
gitlab_url: baseUrl = 'https://gitlab.com', | ||
include_prereleases: pre, | ||
sort, | ||
} | ||
) { | ||
const tags = await this.fetch({ user, repo, baseUrl }) | ||
const version = this.constructor.transform({ | ||
tags, | ||
sort, | ||
includePrereleases: pre !== undefined, | ||
}) | ||
return this.constructor.render({ version, sort }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { expect } from 'chai' | ||
import nock from 'nock' | ||
import { cleanUpNockAfterEach, defaultContext } from '../test-helpers.js' | ||
import GitLabTag from './gitlab-tag.service.js' | ||
|
||
describe('GitLabTag', function () { | ||
describe('auth', function () { | ||
cleanUpNockAfterEach() | ||
|
||
const fakeToken = 'abc123' | ||
const config = { | ||
public: { | ||
services: { | ||
gitlab: { | ||
authorizedOrigins: ['https://gitlab.com'], | ||
}, | ||
}, | ||
}, | ||
private: { | ||
gitlab_token: fakeToken, | ||
}, | ||
} | ||
|
||
it('sends the auth information as configured', async function () { | ||
const scope = nock('https://gitlab.com/') | ||
.get('/api/v4/projects/foo%2Fbar/repository/tags?order_by=updated') | ||
// This ensures that the expected credentials are actually being sent with the HTTP request. | ||
// Without this the request wouldn't match and the test would fail. | ||
.basicAuth({ user: '', pass: fakeToken }) | ||
.reply(200, [{ name: '1.9' }]) | ||
|
||
expect( | ||
await GitLabTag.invoke( | ||
defaultContext, | ||
config, | ||
{ user: 'foo', repo: 'bar' }, | ||
{} | ||
) | ||
).to.deep.equal({ | ||
message: 'v1.9', | ||
color: 'blue', | ||
}) | ||
|
||
scope.done() | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { isSemver } from '../test-validators.js' | ||
import { createServiceTester } from '../tester.js' | ||
export const t = await createServiceTester() | ||
|
||
t.create('Tag (latest by date)') | ||
.get('/shields-ops-group/tag-test.json') | ||
.expectBadge({ label: 'tag', message: 'v2.0.0', color: 'blue' }) | ||
|
||
t.create('Tag (latest by SemVer)') | ||
.get('/shields-ops-group/tag-test.json?sort=semver') | ||
.expectBadge({ label: 'tag', message: 'v4.0.0', color: 'blue' }) | ||
|
||
t.create('Tag (latest by SemVer pre-release)') | ||
.get('/shields-ops-group/tag-test.json?sort=semver&include_prereleases') | ||
.expectBadge({ label: 'tag', message: 'v5.0.0-beta.1', color: 'orange' }) | ||
|
||
t.create('Tag (custom instance') | ||
.get('/GNOME/librsvg.json?gitlab_url=https://gitlab.gnome.org') | ||
.expectBadge({ label: 'tag', message: isSemver, color: 'blue' }) | ||
|
||
t.create('Tag (repo not found)') | ||
.get('/fdroid/nonexistant.json') | ||
.expectBadge({ label: 'tag', message: 'repo not found' }) | ||
|
||
t.create('Tag (no tags)') | ||
.get('/fdroid/fdroiddata.json') | ||
.expectBadge({ label: 'tag', message: 'no tags found' }) |