Compare commits
1 Commits
8535-token
...
integratio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57036a34b0 |
28
.github/actions/close-bot/package-lock.json
generated
vendored
28
.github/actions/close-bot/package-lock.json
generated
vendored
@@ -9,23 +9,23 @@
|
||||
"version": "0.0.0",
|
||||
"license": "CC0",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/github": "^5.1.1"
|
||||
"@actions/core": "^1.9.1",
|
||||
"@actions/github": "^5.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
|
||||
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/github": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
||||
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.3.tgz",
|
||||
"integrity": "sha512-myjA/pdLQfhUGLtRZC/J4L1RXOG4o6aYdiEq+zr5wVVKljzbFld+xv10k1FX6IkIJtNxbAq44BdwSNpQ015P0A==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
@@ -235,18 +235,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
|
||||
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
|
||||
"requires": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"@actions/github": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
||||
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.3.tgz",
|
||||
"integrity": "sha512-myjA/pdLQfhUGLtRZC/J4L1RXOG4o6aYdiEq+zr5wVVKljzbFld+xv10k1FX6IkIJtNxbAq44BdwSNpQ015P0A==",
|
||||
"requires": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
|
||||
4
.github/actions/close-bot/package.json
vendored
4
.github/actions/close-bot/package.json
vendored
@@ -10,7 +10,7 @@
|
||||
"author": "chris48s",
|
||||
"license": "CC0",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/github": "^5.1.1"
|
||||
"@actions/core": "^1.9.1",
|
||||
"@actions/github": "^5.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
4
.github/workflows/auto-close.yml
vendored
4
.github/workflows/auto-close.yml
vendored
@@ -1,7 +1,5 @@
|
||||
name: Auto close
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
on: pull_request_target
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
name: 'Dependency Review'
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
enforce-dependency-review:
|
||||
|
||||
12
.github/workflows/test-integration-17.yml
vendored
12
.github/workflows/test-integration-17.yml
vendored
@@ -4,13 +4,10 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
- 'dependabot/**'
|
||||
|
||||
jobs:
|
||||
test-integration-17:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
PAT_EXISTS: ${{ secrets.GH_PAT != '' }}
|
||||
|
||||
services:
|
||||
redis:
|
||||
@@ -34,14 +31,7 @@ jobs:
|
||||
env:
|
||||
NPM_CONFIG_ENGINE_STRICT: 'false'
|
||||
|
||||
- name: Integration Tests (with PAT)
|
||||
if: ${{ env.PAT_EXISTS == 'true' }}
|
||||
uses: ./.github/actions/integration-tests
|
||||
with:
|
||||
github-token: '${{ secrets.GH_PAT }}'
|
||||
|
||||
- name: Integration Tests (with workflow token)
|
||||
if: ${{ env.PAT_EXISTS == 'false' }}
|
||||
- name: Integration Tests
|
||||
uses: ./.github/actions/integration-tests
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
|
||||
12
.github/workflows/test-integration.yml
vendored
12
.github/workflows/test-integration.yml
vendored
@@ -4,13 +4,10 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
- 'dependabot/**'
|
||||
|
||||
jobs:
|
||||
test-integration:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
PAT_EXISTS: ${{ secrets.GH_PAT != '' }}
|
||||
|
||||
services:
|
||||
redis:
|
||||
@@ -32,14 +29,7 @@ jobs:
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Integration Tests (with PAT)
|
||||
if: ${{ env.PAT_EXISTS == 'true' }}
|
||||
uses: ./.github/actions/integration-tests
|
||||
with:
|
||||
github-token: '${{ secrets.GH_PAT }}'
|
||||
|
||||
- name: Integration Tests (with workflow token)
|
||||
if: ${{ env.PAT_EXISTS == 'false' }}
|
||||
- name: Integration Tests
|
||||
uses: ./.github/actions/integration-tests
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
|
||||
1
.github/workflows/test-lint.yml
vendored
1
.github/workflows/test-lint.yml
vendored
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
- 'dependabot/**'
|
||||
|
||||
jobs:
|
||||
test-lint:
|
||||
|
||||
1
.github/workflows/test-main-17.yml
vendored
1
.github/workflows/test-main-17.yml
vendored
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
- 'dependabot/**'
|
||||
|
||||
jobs:
|
||||
test-main-17:
|
||||
|
||||
1
.github/workflows/test-main.yml
vendored
1
.github/workflows/test-main.yml
vendored
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
- 'dependabot/**'
|
||||
|
||||
jobs:
|
||||
test-main:
|
||||
|
||||
1
.github/workflows/test-package-cli.yml
vendored
1
.github/workflows/test-package-cli.yml
vendored
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
- 'dependabot/**'
|
||||
|
||||
# Smoke test (render a badge with the CLI) with only the package
|
||||
# dependencies installed.
|
||||
|
||||
1
.github/workflows/test-package-lib.yml
vendored
1
.github/workflows/test-package-lib.yml
vendored
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
- 'dependabot/**'
|
||||
|
||||
jobs:
|
||||
test-package-lib:
|
||||
|
||||
18
CHANGELOG.md
18
CHANGELOG.md
@@ -4,24 +4,6 @@ Note: this changelog is for the shields.io server. The changelog for the badge-m
|
||||
|
||||
---
|
||||
|
||||
## server-2022-10-08
|
||||
|
||||
- deprecate [criterion] service [#8501](https://github.com/badges/shields/issues/8501)
|
||||
- fix formatRelativeDate error handling; run [date] [#8497](https://github.com/badges/shields/issues/8497)
|
||||
- allow/validate bitbucket_username / bitbucket_password in private config schema [#8472](https://github.com/badges/shields/issues/8472)
|
||||
- fix [pub] points badge test and example [#8498](https://github.com/badges/shields/issues/8498)
|
||||
- feat: add [GitlabLanguageCount] service [#8377](https://github.com/badges/shields/issues/8377)
|
||||
- [GitHubGistStars] add GitHub Gist Stars [#8471](https://github.com/badges/shields/issues/8471)
|
||||
- fix display/search of CII badge examples [#8473](https://github.com/badges/shields/issues/8473)
|
||||
- feat: add 2022 support to GitHub Hacktoberfest [#8468](https://github.com/badges/shields/issues/8468)
|
||||
- fix [GitLabCoverage] subgroup bug [#8401](https://github.com/badges/shields/issues/8401)
|
||||
- implement ruby gems-specific version sort/color functions [#8434](https://github.com/badges/shields/issues/8434)
|
||||
- Add `rc` to pre-release identifiers [#8435](https://github.com/badges/shields/issues/8435)
|
||||
- add [GitHub] Number of commits between branches/tags/commits [#8394](https://github.com/badges/shields/issues/8394)
|
||||
- add [Packagist] dependency version [#8371](https://github.com/badges/shields/issues/8371)
|
||||
- fix Docker build status invalid response data bug [#8392](https://github.com/badges/shields/issues/8392)
|
||||
- Dependency updates
|
||||
|
||||
## server-2022-09-04
|
||||
|
||||
- fix frontend compile for users running on Windows [#8350](https://github.com/badges/shields/issues/8350)
|
||||
|
||||
@@ -134,7 +134,7 @@ Prettier before a commit by default.
|
||||
When adding or changing a service [please write tests][service-tests], and ensure the [title of your Pull Requests follows the required conventions](#running-service-tests-in-pull-requests) to ensure your tests are executed.
|
||||
When changing other code, please add unit tests.
|
||||
|
||||
To run the integration tests, you must have Redis installed and in your PATH.
|
||||
To run the integration tests, you must have redis installed and in your PATH.
|
||||
Use `brew install redis`, `yum install redis`, etc. The test runner will
|
||||
start the server automatically.
|
||||
|
||||
|
||||
@@ -169,8 +169,6 @@ const privateConfigSchema = Joi.object({
|
||||
jenkins_pass: Joi.string(),
|
||||
jira_user: Joi.string(),
|
||||
jira_pass: Joi.string(),
|
||||
bitbucket_username: Joi.string(),
|
||||
bitbucket_password: Joi.string(),
|
||||
bitbucket_server_username: Joi.string(),
|
||||
bitbucket_server_password: Joi.string(),
|
||||
librariesio_tokens: Joi.arrayFromString().items(Joi.string()),
|
||||
|
||||
3915
package-lock.json
generated
3915
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
49
package.json
49
package.json
@@ -21,16 +21,15 @@
|
||||
"url": "https://github.com/badges/shields"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/lato": "^4.5.10",
|
||||
"@fontsource/lekton": "^4.5.11",
|
||||
"@fontsource/lato": "^4.5.9",
|
||||
"@fontsource/lekton": "^4.5.10",
|
||||
"@renovate/pep440": "^1.0.0",
|
||||
"@renovatebot/ruby-semver": "^1.1.6",
|
||||
"@sentry/node": "^7.15.0",
|
||||
"@sentry/node": "^7.13.0",
|
||||
"@shields_io/camp": "^18.1.1",
|
||||
"badge-maker": "file:badge-maker",
|
||||
"bytes": "^3.1.2",
|
||||
"camelcase": "^7.0.0",
|
||||
"chalk": "^5.1.2",
|
||||
"chalk": "^5.0.1",
|
||||
"check-node-version": "^4.2.1",
|
||||
"cloudflare-middleware": "^1.0.4",
|
||||
"config": "^3.3.8",
|
||||
@@ -39,14 +38,14 @@
|
||||
"decamelize": "^3.2.0",
|
||||
"emojic": "^1.1.17",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"fast-xml-parser": "^4.0.11",
|
||||
"fast-xml-parser": "^4.0.10",
|
||||
"glob": "^8.0.3",
|
||||
"global-agent": "^3.0.0",
|
||||
"got": "^12.5.2",
|
||||
"got": "^12.4.1",
|
||||
"graphql": "^15.6.1",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"ioredis": "5.2.3",
|
||||
"joi": "17.6.3",
|
||||
"joi": "17.6.0",
|
||||
"joi-extension-semver": "5.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jsonpath": "~1.1.1",
|
||||
@@ -61,8 +60,8 @@
|
||||
"prom-client": "^14.1.0",
|
||||
"qs": "^6.11.0",
|
||||
"query-string": "^7.1.1",
|
||||
"semver": "~7.3.8",
|
||||
"simple-icons": "7.15.0",
|
||||
"semver": "~7.3.7",
|
||||
"simple-icons": "7.11.0",
|
||||
"webextension-store-meta": "^1.0.5",
|
||||
"xmldom": "~0.6.0",
|
||||
"xpath": "~0.0.32"
|
||||
@@ -142,7 +141,7 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.3",
|
||||
"@babel/core": "^7.19.1",
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/register": "7.18.9",
|
||||
"@istanbuljs/schema": "^0.1.3",
|
||||
@@ -156,7 +155,7 @@
|
||||
"@types/react-modal": "^3.13.1",
|
||||
"@types/react-select": "^4.0.17",
|
||||
"@types/styled-components": "5.1.26",
|
||||
"@typescript-eslint/eslint-plugin": "^5.40.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.37.0",
|
||||
"@typescript-eslint/parser": "^5.30.7",
|
||||
"babel-plugin-inline-react-svg": "^2.0.1",
|
||||
"babel-preset-gatsby": "^2.22.0",
|
||||
@@ -169,9 +168,9 @@
|
||||
"child-process-promise": "^2.2.1",
|
||||
"clipboard-copy": "^4.0.1",
|
||||
"concurrently": "^7.4.0",
|
||||
"cypress": "^10.10.0",
|
||||
"cypress-wait-for-stable-dom": "^0.0.4",
|
||||
"danger": "^11.1.4",
|
||||
"cypress": "^10.8.0",
|
||||
"cypress-wait-for-stable-dom": "^0.0.3",
|
||||
"danger": "^11.1.2",
|
||||
"danger-plugin-no-test-shortcuts": "^2.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"eslint": "^7.32.0",
|
||||
@@ -187,17 +186,17 @@
|
||||
"eslint-plugin-no-extension-in-require": "^0.2.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.2.0",
|
||||
"eslint-plugin-react": "^7.31.10",
|
||||
"eslint-plugin-react": "^7.31.8",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-sort-class-members": "^1.15.2",
|
||||
"fetch-ponyfill": "^7.1.0",
|
||||
"form-data": "^4.0.0",
|
||||
"gatsby": "4.23.1",
|
||||
"gatsby": "4.23.0",
|
||||
"gatsby-plugin-catch-links": "^4.19.0",
|
||||
"gatsby-plugin-page-creator": "^4.24.0",
|
||||
"gatsby-plugin-page-creator": "^4.22.0",
|
||||
"gatsby-plugin-react-helmet": "^5.22.0",
|
||||
"gatsby-plugin-remove-trailing-slashes": "^4.9.0",
|
||||
"gatsby-plugin-styled-components": "^5.24.0",
|
||||
"gatsby-plugin-styled-components": "^5.19.0",
|
||||
"gatsby-plugin-typescript": "^4.22.0",
|
||||
"humanize-string": "^2.1.0",
|
||||
"icedfrisby": "4.0.0",
|
||||
@@ -208,16 +207,16 @@
|
||||
"lint-staged": "^13.0.3",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.difference": "^4.5.0",
|
||||
"minimist": "^1.2.7",
|
||||
"minimist": "^1.2.6",
|
||||
"mocha": "^9.2.2",
|
||||
"mocha-env-reporter": "^4.0.0",
|
||||
"mocha-junit-reporter": "^2.1.0",
|
||||
"mocha-junit-reporter": "^2.0.2",
|
||||
"mocha-yaml-loader": "^1.0.3",
|
||||
"nock": "13.2.9",
|
||||
"node-mocks-http": "^1.11.0",
|
||||
"nodemon": "^2.0.20",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"open-cli": "^7.1.0",
|
||||
"open-cli": "^7.0.1",
|
||||
"portfinder": "^1.0.32",
|
||||
"prettier": "2.7.1",
|
||||
"react": "^17.0.2",
|
||||
@@ -232,14 +231,14 @@
|
||||
"rimraf": "^3.0.2",
|
||||
"sazerac": "^2.0.0",
|
||||
"simple-git-hooks": "^2.8.0",
|
||||
"sinon": "^14.0.1",
|
||||
"sinon": "^14.0.0",
|
||||
"sinon-chai": "^3.7.0",
|
||||
"snap-shot-it": "^7.9.6",
|
||||
"start-server-and-test": "1.14.0",
|
||||
"styled-components": "^5.3.6",
|
||||
"styled-components": "^5.3.5",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"tsd": "^0.24.1",
|
||||
"typescript": "^4.8.4",
|
||||
"typescript": "^4.8.3",
|
||||
"url": "^0.11.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -20,7 +20,7 @@ t.create('pr-raw (not found)')
|
||||
|
||||
t.create('pr-raw (private repo)')
|
||||
.get('/pr-raw/chris48s/example-private-repo.json')
|
||||
.expectBadge({ label: 'pull requests', message: 'not found' })
|
||||
.expectBadge({ label: 'pull requests', message: 'private repo' })
|
||||
|
||||
t.create('pr (valid)').get('/pr/atlassian/python-bitbucket.json').expectBadge({
|
||||
label: 'pull requests',
|
||||
@@ -33,7 +33,7 @@ t.create('pr (not found)')
|
||||
|
||||
t.create('pr (private repo)')
|
||||
.get('/pr/chris48s/example-private-repo.json')
|
||||
.expectBadge({ label: 'pull requests', message: 'not found' })
|
||||
.expectBadge({ label: 'pull requests', message: 'private repo' })
|
||||
|
||||
t.create('pr (server)')
|
||||
.get('/pr/project/repo.json?server=https://bitbucket.mydomain.net')
|
||||
|
||||
@@ -35,7 +35,7 @@ export default class CIIBestPracticesService extends BaseJsonService {
|
||||
pattern: ':metric(level|percentage|summary)/:projectId',
|
||||
}
|
||||
|
||||
static examples = [
|
||||
static exampless = [
|
||||
{
|
||||
title: 'CII Best Practices Level',
|
||||
pattern: 'level/:projectId',
|
||||
|
||||
@@ -23,7 +23,7 @@ function version(version) {
|
||||
if (first === 'v') {
|
||||
first = version[1]
|
||||
}
|
||||
if (first === '0' || /alpha|beta|snapshot|dev|pre|rc/i.test(version)) {
|
||||
if (first === '0' || /alpha|beta|snapshot|dev|pre/i.test(version)) {
|
||||
return 'orange'
|
||||
} else {
|
||||
return 'blue'
|
||||
|
||||
@@ -88,7 +88,6 @@ describe('Color formatters', function () {
|
||||
given('6.0-SNAPSHOT'),
|
||||
given('1.0.1-dev'),
|
||||
given('2.1.6-prerelease'),
|
||||
given('2.1.6-RC1'),
|
||||
]).expect('orange')
|
||||
|
||||
expect(() => version(null)).to.throw(
|
||||
|
||||
@@ -1,11 +1,66 @@
|
||||
import { deprecatedService } from '../index.js'
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import {
|
||||
IMPROVED_STATUS,
|
||||
NOT_FOUND_STATUS,
|
||||
REGRESSED_STATUS,
|
||||
NO_CHANGE_STATUS,
|
||||
} from './constants.js'
|
||||
|
||||
export default deprecatedService({
|
||||
category: 'analysis',
|
||||
route: {
|
||||
base: 'criterion',
|
||||
pattern: ':various*',
|
||||
},
|
||||
label: 'criterion',
|
||||
dateAdded: new Date('2022-10-07'),
|
||||
})
|
||||
const schema = Joi.string()
|
||||
.allow(IMPROVED_STATUS, REGRESSED_STATUS, NO_CHANGE_STATUS)
|
||||
.required()
|
||||
|
||||
/**
|
||||
* Criterion Badge Service
|
||||
*
|
||||
* Support and Contact:
|
||||
* - https://github.com/chmoder/api.criterion.dev
|
||||
*
|
||||
* API Documentation:
|
||||
* - https://app.swaggerhub.com/apis-docs/chmoder/Criterion.dev
|
||||
*/
|
||||
export default class Criterion extends BaseJsonService {
|
||||
static category = 'analysis'
|
||||
static route = { base: 'criterion', pattern: ':user/:repo' }
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'Criterion',
|
||||
namedParams: {
|
||||
user: 'chmoder',
|
||||
repo: 'data_vault',
|
||||
},
|
||||
staticPreview: this.render({ status: IMPROVED_STATUS }),
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'criterion' }
|
||||
|
||||
static render({ status }) {
|
||||
let statusColor = 'lightgrey'
|
||||
|
||||
if (status === IMPROVED_STATUS) {
|
||||
statusColor = 'brightgreen'
|
||||
} else if (status === NO_CHANGE_STATUS) {
|
||||
statusColor = 'green'
|
||||
} else if (statusColor === REGRESSED_STATUS) {
|
||||
statusColor = 'red'
|
||||
}
|
||||
|
||||
return {
|
||||
message: `${status}`,
|
||||
color: statusColor,
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ user, repo }) {
|
||||
const status = await this._requestJson({
|
||||
url: `https://api.criterion.dev/v1/${user}/${repo}/status`,
|
||||
errorMessages: { 404: NOT_FOUND_STATUS },
|
||||
schema,
|
||||
})
|
||||
|
||||
return this.constructor.render({ status })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
import { ServiceTester } from '../tester.js'
|
||||
import Joi from 'joi'
|
||||
import { createServiceTester } from '../tester.js'
|
||||
import {
|
||||
IMPROVED_STATUS,
|
||||
REGRESSED_STATUS,
|
||||
NO_CHANGE_STATUS,
|
||||
NOT_FOUND_STATUS,
|
||||
} from './constants.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
export const t = new ServiceTester({
|
||||
id: 'criterion',
|
||||
title: 'Criterion',
|
||||
pathPrefix: '/criterion',
|
||||
})
|
||||
const isStatus = Joi.string()
|
||||
.allow(IMPROVED_STATUS, REGRESSED_STATUS, NOT_FOUND_STATUS, NO_CHANGE_STATUS)
|
||||
.required()
|
||||
|
||||
t.create('Criterion')
|
||||
t.create('Criterion (valid repo)')
|
||||
.get('/chmoder/credit_card.json')
|
||||
.expectBadge({ label: 'criterion', message: 'no longer available' })
|
||||
.expectBadge({ label: 'criterion', message: isStatus })
|
||||
|
||||
t.create('Criterion (not found)')
|
||||
.get('/chmoder/not-a-repo.json')
|
||||
.expectBadge({ label: 'criterion', message: NOT_FOUND_STATUS })
|
||||
|
||||
@@ -4,10 +4,9 @@ import { BaseJsonService, InvalidResponse, NotFound } from '../index.js'
|
||||
|
||||
/**
|
||||
* Validates that the schema response is what we're expecting.
|
||||
* The username pattern should match the requirements in the freeCodeCamp
|
||||
* repository.
|
||||
* The username pattern should match the freeCodeCamp repository.
|
||||
*
|
||||
* @see https://github.com/freeCodeCamp/freeCodeCamp/blob/main/utils/validate.js
|
||||
* @see https://github.com/freeCodeCamp/freeCodeCamp/blob/main/utils/validate.js#L14
|
||||
*/
|
||||
const schema = Joi.object({
|
||||
entities: Joi.object({
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { valid, maxSatisfying, prerelease } from '@renovatebot/ruby-semver'
|
||||
|
||||
function latest(versions) {
|
||||
// latest Ruby Gems version, including pre-releases
|
||||
return maxSatisfying(versions, '>0')
|
||||
}
|
||||
|
||||
function versionColor(version) {
|
||||
if (!valid(version)) {
|
||||
return 'lightgrey'
|
||||
}
|
||||
|
||||
version = `${version}`
|
||||
let first = version[0]
|
||||
if (first === 'v') {
|
||||
first = version[1]
|
||||
}
|
||||
|
||||
if (first === '0' || prerelease(version)) {
|
||||
return 'orange'
|
||||
}
|
||||
return 'blue'
|
||||
}
|
||||
|
||||
export { latest, versionColor }
|
||||
@@ -1,17 +0,0 @@
|
||||
import { test, given } from 'sazerac'
|
||||
import { latest, versionColor } from './gem-helpers.js'
|
||||
|
||||
describe('Gem helpers', function () {
|
||||
test(latest, () => {
|
||||
given(['2.0.0', '2.0.0.beta1']).expect('2.0.0')
|
||||
given(['2.0.0.beta1', '1.9.0']).expect('2.0.0.beta1')
|
||||
given(['0.0.1', '0.0.2']).expect('0.0.2')
|
||||
})
|
||||
|
||||
test(versionColor, () => {
|
||||
given('1.9.0').expect('blue')
|
||||
given('2.0.0.beta1').expect('orange')
|
||||
given('0.0.1').expect('orange')
|
||||
given('v1').expect('lightgrey')
|
||||
})
|
||||
})
|
||||
@@ -1,7 +1,12 @@
|
||||
import Joi from 'joi'
|
||||
import { createServiceTester } from '../tester.js'
|
||||
import { isOrdinalNumber, isOrdinalNumberDaily } from '../test-validators.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
const isOrdinalNumber = Joi.string().regex(/^[1-9][0-9]+(ᵗʰ|ˢᵗ|ⁿᵈ|ʳᵈ)$/)
|
||||
const isOrdinalNumberDaily = Joi.string().regex(
|
||||
/^[1-9][0-9]*(ᵗʰ|ˢᵗ|ⁿᵈ|ʳᵈ) daily$/
|
||||
)
|
||||
|
||||
t.create('total rank (valid)').get('/rt/rspec-puppet-facts.json').expectBadge({
|
||||
label: 'rank',
|
||||
message: isOrdinalNumber,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import Joi from 'joi'
|
||||
import { renderVersionBadge } from '../version.js'
|
||||
import { renderVersionBadge, latest } from '../version.js'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { latest, versionColor } from './gem-helpers.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
// In most cases `version` will be a SemVer but the registry doesn't
|
||||
@@ -46,7 +45,7 @@ export default class GemVersion extends BaseJsonService {
|
||||
static defaultBadgeData = { label: 'gem' }
|
||||
|
||||
static render({ version }) {
|
||||
return renderVersionBadge({ version, versionFormatter: versionColor })
|
||||
return renderVersionBadge({ version })
|
||||
}
|
||||
|
||||
async fetch({ gem }) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { documentation, transformErrors } from './github-helpers.js'
|
||||
const greenStates = ['SUCCESS']
|
||||
const redStates = ['ERROR', 'FAILURE']
|
||||
const blueStates = ['INACTIVE']
|
||||
const otherStates = ['IN_PROGRESS', 'QUEUED', 'PENDING', 'NO_STATUS', 'WAITING']
|
||||
const otherStates = ['IN_PROGRESS', 'QUEUED', 'PENDING', 'NO_STATUS']
|
||||
|
||||
const stateToMessageMappings = {
|
||||
IN_PROGRESS: 'in progress',
|
||||
|
||||
@@ -21,12 +21,6 @@ describe('GithubDeployments', function () {
|
||||
message: 'in progress',
|
||||
color: undefined,
|
||||
})
|
||||
given({
|
||||
state: 'WAITING',
|
||||
}).expect({
|
||||
message: 'waiting',
|
||||
color: undefined,
|
||||
})
|
||||
given({
|
||||
state: 'NO_STATUS',
|
||||
}).expect({
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
import gql from 'graphql-tag'
|
||||
import Joi from 'joi'
|
||||
import { metric } from '../text-formatters.js'
|
||||
import { NotFound } from '../index.js'
|
||||
import { GithubAuthV4Service } from './github-auth-service.js'
|
||||
import { documentation as commonDocumentation } from './github-helpers.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
data: Joi.object({
|
||||
viewer: Joi.object({
|
||||
gist: Joi.object({
|
||||
stargazerCount: Joi.number().required(),
|
||||
url: Joi.string().required(),
|
||||
owner: Joi.object({
|
||||
login: Joi.string().required(),
|
||||
}).required(),
|
||||
name: Joi.string().required(),
|
||||
}).allow(null),
|
||||
}).required(),
|
||||
}).required(),
|
||||
}).required()
|
||||
|
||||
const documentation = `${commonDocumentation}
|
||||
<p>This badge shows the number of stargazers for a gist. Gist id is accepted as input and 'gist not found' is returned if the gist is not found for the given gist id.
|
||||
</p>`
|
||||
|
||||
export default class GithubGistStars extends GithubAuthV4Service {
|
||||
static category = 'social'
|
||||
|
||||
static route = {
|
||||
base: 'github/stars/gists',
|
||||
pattern: ':gistId',
|
||||
}
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'Github Gist stars',
|
||||
namedParams: { gistId: '47a4d00457a92aa426dbd48a18776322' },
|
||||
staticPreview: {
|
||||
label: this.defaultBadgeData.label,
|
||||
message: metric(29),
|
||||
style: 'social',
|
||||
},
|
||||
documentation,
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = {
|
||||
label: 'Stars',
|
||||
color: 'blue',
|
||||
namedLogo: 'github',
|
||||
}
|
||||
|
||||
static render({ stargazerCount, url, stargazers }) {
|
||||
return { message: metric(stargazerCount), link: [url, stargazers] }
|
||||
}
|
||||
|
||||
async fetch({ gistId }) {
|
||||
const data = await this._requestGraphql({
|
||||
query: gql`
|
||||
query ($gistId: String!) {
|
||||
viewer {
|
||||
gist(name: $gistId) {
|
||||
stargazerCount
|
||||
url
|
||||
name
|
||||
owner {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
gistId,
|
||||
},
|
||||
schema,
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
static transform({ data }) {
|
||||
const {
|
||||
data: {
|
||||
viewer: { gist },
|
||||
},
|
||||
} = data
|
||||
|
||||
if (!gist) {
|
||||
throw new NotFound({ prettyMessage: 'gist not found' })
|
||||
}
|
||||
|
||||
const {
|
||||
stargazerCount,
|
||||
url,
|
||||
name,
|
||||
owner: { login },
|
||||
} = gist
|
||||
|
||||
const stargazers = `https://gist.github.com/${login}/${name}/stargazers`
|
||||
|
||||
return { stargazerCount, url, stargazers }
|
||||
}
|
||||
|
||||
async handle({ gistId }) {
|
||||
const data = await this.fetch({ gistId })
|
||||
const { stargazerCount, url, stargazers } =
|
||||
await this.constructor.transform({
|
||||
data,
|
||||
})
|
||||
return this.constructor.render({ stargazerCount, url, stargazers })
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { createServiceTester } from '../tester.js'
|
||||
import { isMetric } from '../test-validators.js'
|
||||
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('Gist Total Stars')
|
||||
.get('/47a4d00457a92aa426dbd48a18776322.json')
|
||||
.expectBadge({
|
||||
label: 'Stars',
|
||||
message: isMetric,
|
||||
color: 'blue',
|
||||
link: [
|
||||
'https://gist.github.com/47a4d00457a92aa426dbd48a18776322',
|
||||
'https://gist.github.com/maratori/47a4d00457a92aa426dbd48a18776322/stargazers',
|
||||
],
|
||||
})
|
||||
|
||||
t.create('Gist Total Stars (Not Found)')
|
||||
.get('/invalid-gist-id.json')
|
||||
.expectBadge({
|
||||
label: 'Stars',
|
||||
message: 'gist not found',
|
||||
color: 'red',
|
||||
link: [],
|
||||
})
|
||||
@@ -60,7 +60,7 @@ export default class GithubHacktoberfestCombinedStatus extends GithubAuthV4Servi
|
||||
static category = 'issue-tracking'
|
||||
static route = {
|
||||
base: 'github/hacktoberfest',
|
||||
pattern: ':year(2019|2020|2021|2022)/:user/:repo',
|
||||
pattern: ':year(2019|2020|2021)/:user/:repo',
|
||||
queryParamSchema,
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export default class GithubHacktoberfestCombinedStatus extends GithubAuthV4Servi
|
||||
{
|
||||
title: 'GitHub Hacktoberfest combined status',
|
||||
namedParams: {
|
||||
year: '2022',
|
||||
year: '2021',
|
||||
user: 'snyk',
|
||||
repo: 'snyk',
|
||||
},
|
||||
@@ -82,7 +82,7 @@ export default class GithubHacktoberfestCombinedStatus extends GithubAuthV4Servi
|
||||
{
|
||||
title: 'GitHub Hacktoberfest combined status (suggestion label override)',
|
||||
namedParams: {
|
||||
year: '2022',
|
||||
year: '2021',
|
||||
user: 'tmrowco',
|
||||
repo: 'tmrowapp-contrib',
|
||||
},
|
||||
@@ -90,7 +90,7 @@ export default class GithubHacktoberfestCombinedStatus extends GithubAuthV4Servi
|
||||
suggestion_label: 'help wanted',
|
||||
},
|
||||
staticPreview: this.render({
|
||||
year: '2022',
|
||||
year: '2021',
|
||||
suggestedIssueCount: 12,
|
||||
contributionCount: 8,
|
||||
daysLeft: 15,
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { redirector } from '../index.js'
|
||||
|
||||
export default redirector({
|
||||
category: 'coverage',
|
||||
route: {
|
||||
base: 'gitlab/coverage',
|
||||
pattern: ':user/:repo/:branch',
|
||||
},
|
||||
transformPath: ({ user, repo }) =>
|
||||
`/gitlab/pipeline-coverage/${user}/${repo}`,
|
||||
transformQueryParams: ({ branch }) => ({ branch }),
|
||||
dateAdded: new Date('2022-09-25'),
|
||||
})
|
||||
@@ -1,22 +0,0 @@
|
||||
import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('Coverage redirect (with branch)')
|
||||
.get('/gitlab-org/gitlab-runner/master.json')
|
||||
.expectRedirect(
|
||||
'/gitlab/pipeline-coverage/gitlab-org/gitlab-runner.json?branch=master'
|
||||
)
|
||||
|
||||
t.create('Coverage redirect (with branch and job_name)')
|
||||
.get('/gitlab-org/gitlab-runner/master.json?job_name=test coverage report')
|
||||
.expectRedirect(
|
||||
'/gitlab/pipeline-coverage/gitlab-org/gitlab-runner.json?branch=master&job_name=test%20coverage%20report'
|
||||
)
|
||||
|
||||
t.create('Coverage redirect (with branch and gitlab_url)')
|
||||
.get(
|
||||
'/gitlab-org/gitlab-runner/master.json?gitlab_url=https://gitlab.gnome.org'
|
||||
)
|
||||
.expectRedirect(
|
||||
'/gitlab/pipeline-coverage/gitlab-org/gitlab-runner.json?branch=master&gitlab_url=https%3a%2f%2fgitlab.gnome.org'
|
||||
)
|
||||
@@ -13,7 +13,6 @@ const schema = Joi.object({
|
||||
const queryParamSchema = Joi.object({
|
||||
gitlab_url: optionalUrl,
|
||||
job_name: Joi.string(),
|
||||
branch: Joi.string(),
|
||||
}).required()
|
||||
|
||||
const moreDocs = `
|
||||
@@ -38,44 +37,50 @@ Also make sure you have set up code covrage parsing as described <a href="https:
|
||||
</p>
|
||||
`
|
||||
|
||||
export default class GitlabPipelineCoverage extends BaseSvgScrapingService {
|
||||
export default class GitlabCoverage extends BaseSvgScrapingService {
|
||||
static category = 'coverage'
|
||||
|
||||
static route = {
|
||||
base: 'gitlab/pipeline-coverage',
|
||||
pattern: ':project+',
|
||||
base: 'gitlab/coverage',
|
||||
pattern: ':user/:repo/:branch',
|
||||
queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'Gitlab code coverage',
|
||||
namedParams: { project: 'gitlab-org/gitlab-runner' },
|
||||
queryParams: { branch: 'master' },
|
||||
namedParams: {
|
||||
user: 'gitlab-org',
|
||||
repo: 'gitlab-runner',
|
||||
branch: 'master',
|
||||
},
|
||||
staticPreview: this.render({ coverage: 67 }),
|
||||
documentation: documentation + moreDocs,
|
||||
},
|
||||
{
|
||||
title: 'Gitlab code coverage (specific job)',
|
||||
namedParams: { project: 'gitlab-org/gitlab-runner' },
|
||||
queryParams: { job_name: 'test coverage report', branch: 'master' },
|
||||
namedParams: {
|
||||
user: 'gitlab-org',
|
||||
repo: 'gitlab-runner',
|
||||
branch: 'master',
|
||||
},
|
||||
queryParams: { job_name: 'test coverage report' },
|
||||
staticPreview: this.render({ coverage: 96 }),
|
||||
documentation: documentation + moreDocs,
|
||||
},
|
||||
{
|
||||
title: 'Gitlab code coverage (self-managed)',
|
||||
namedParams: { project: 'GNOME/at-spi2-core' },
|
||||
queryParams: { gitlab_url: 'https://gitlab.gnome.org', branch: 'master' },
|
||||
namedParams: { user: 'GNOME', repo: 'at-spi2-core', branch: 'master' },
|
||||
queryParams: { gitlab_url: 'https://gitlab.gnome.org' },
|
||||
staticPreview: this.render({ coverage: 93 }),
|
||||
documentation: documentation + moreDocs,
|
||||
},
|
||||
{
|
||||
title: 'Gitlab code coverage (self-managed, specific job)',
|
||||
namedParams: { project: 'GNOME/libhandy' },
|
||||
namedParams: { user: 'GNOME', repo: 'libhandy', branch: 'master' },
|
||||
queryParams: {
|
||||
gitlab_url: 'https://gitlab.gnome.org',
|
||||
job_name: 'unit-test',
|
||||
branch: 'master',
|
||||
},
|
||||
staticPreview: this.render({ coverage: 93 }),
|
||||
documentation: documentation + moreDocs,
|
||||
@@ -91,13 +96,11 @@ export default class GitlabPipelineCoverage extends BaseSvgScrapingService {
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ project, baseUrl = 'https://gitlab.com', jobName, branch }) {
|
||||
async fetch({ user, repo, branch, baseUrl = 'https://gitlab.com', jobName }) {
|
||||
// Since the URL doesn't return a usable value when an invalid job name is specified,
|
||||
// it is recommended to not use the query param at all if not required
|
||||
jobName = jobName ? `?job=${jobName}` : ''
|
||||
const url = `${baseUrl}/${decodeURIComponent(
|
||||
project
|
||||
)}/badges/${branch}/coverage.svg${jobName}`
|
||||
const url = `${baseUrl}/${user}/${repo}/badges/${branch}/coverage.svg${jobName}`
|
||||
const errorMessages = errorMessagesFor('project not found')
|
||||
return this._requestSvg({
|
||||
schema,
|
||||
@@ -114,11 +117,12 @@ export default class GitlabPipelineCoverage extends BaseSvgScrapingService {
|
||||
}
|
||||
|
||||
async handle(
|
||||
{ project },
|
||||
{ gitlab_url: baseUrl, job_name: jobName, branch }
|
||||
{ user, repo, branch },
|
||||
{ gitlab_url: baseUrl, job_name: jobName }
|
||||
) {
|
||||
const { message: coverage } = await this.fetch({
|
||||
project,
|
||||
user,
|
||||
repo,
|
||||
branch,
|
||||
baseUrl,
|
||||
jobName,
|
||||
@@ -3,28 +3,28 @@ import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('Coverage (branch)')
|
||||
.get('/gitlab-org/gitlab-runner.json?branch=12-0-stable')
|
||||
.get('/gitlab-org/gitlab-runner/12-0-stable.json')
|
||||
.expectBadge({
|
||||
label: 'coverage',
|
||||
message: isIntegerPercentage,
|
||||
})
|
||||
|
||||
t.create('Coverage (existent branch but coverage not set up)')
|
||||
.get('/gitlab-org/gitlab-git-http-server.json?branch=master')
|
||||
.get('/gitlab-org/gitlab-git-http-server/master.json')
|
||||
.expectBadge({
|
||||
label: 'coverage',
|
||||
message: 'not set up',
|
||||
})
|
||||
|
||||
t.create('Coverage (nonexistent branch)')
|
||||
.get('/gitlab-org/gitlab-runner.json?branch=nope-not-a-branch')
|
||||
.get('/gitlab-org/gitlab-runner/nope-not-a-branch.json')
|
||||
.expectBadge({
|
||||
label: 'coverage',
|
||||
message: 'not set up',
|
||||
})
|
||||
|
||||
t.create('Coverage (nonexistent repo)')
|
||||
.get('/this-repo/does-not-exist.json')
|
||||
.get('/this-repo/does-not-exist/neither-branch.json')
|
||||
.expectBadge({
|
||||
label: 'coverage',
|
||||
message: 'inaccessible',
|
||||
@@ -32,7 +32,7 @@ t.create('Coverage (nonexistent repo)')
|
||||
|
||||
t.create('Coverage (custom job)')
|
||||
.get(
|
||||
'/gitlab-org/gitlab-runner.json?branch=12-0-stable&job_name=test coverage report'
|
||||
'/gitlab-org/gitlab-runner/12-0-stable.json?job_name=test coverage report'
|
||||
)
|
||||
.expectBadge({
|
||||
label: 'coverage',
|
||||
@@ -40,18 +40,14 @@ t.create('Coverage (custom job)')
|
||||
})
|
||||
|
||||
t.create('Coverage (custom invalid job)')
|
||||
.get(
|
||||
'/gitlab-org/gitlab-runner.json?branch=12-0-stable&job_name=i dont exist'
|
||||
)
|
||||
.get('/gitlab-org/gitlab-runner/12-0-stable.json?job_name=i dont exist')
|
||||
.expectBadge({
|
||||
label: 'coverage',
|
||||
message: 'not set up',
|
||||
})
|
||||
|
||||
t.create('Coverage (custom gitlab URL)')
|
||||
.get(
|
||||
'/GNOME/at-spi2-core.json?gitlab_url=https://gitlab.gnome.org&branch=master'
|
||||
)
|
||||
.get('/GNOME/at-spi2-core/master.json?gitlab_url=https://gitlab.gnome.org')
|
||||
.expectBadge({
|
||||
label: 'coverage',
|
||||
message: isIntegerPercentage,
|
||||
@@ -59,7 +55,7 @@ t.create('Coverage (custom gitlab URL)')
|
||||
|
||||
t.create('Coverage (custom gitlab URL and job)')
|
||||
.get(
|
||||
'/GNOME/libhandy.json?gitlab_url=https://gitlab.gnome.org&branch=master&job_name=unit-test'
|
||||
'/GNOME/libhandy/master.json?gitlab_url=https://gitlab.gnome.org&job_name=unit-test'
|
||||
)
|
||||
.expectBadge({
|
||||
label: 'coverage',
|
||||
@@ -1,68 +0,0 @@
|
||||
import Joi from 'joi'
|
||||
import { optionalUrl } from '../validators.js'
|
||||
import { metric } from '../text-formatters.js'
|
||||
import { documentation, errorMessagesFor } from './gitlab-helper.js'
|
||||
import GitLabBase from './gitlab-base.js'
|
||||
|
||||
/*
|
||||
We're expecting a response like { "Ruby": 67.13, "JavaScript": 19.66 }
|
||||
The keys could be anything and {} is a valid response (e.g: for an empty project)
|
||||
*/
|
||||
const schema = Joi.object().pattern(/./, Joi.number().min(0).max(100))
|
||||
|
||||
const queryParamSchema = Joi.object({
|
||||
gitlab_url: optionalUrl,
|
||||
}).required()
|
||||
|
||||
export default class GitlabLanguageCount extends GitLabBase {
|
||||
static category = 'analysis'
|
||||
|
||||
static route = {
|
||||
base: 'gitlab/languages/count',
|
||||
pattern: ':project+',
|
||||
queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'GitLab language count',
|
||||
namedParams: {
|
||||
project: 'gitlab-org/gitlab',
|
||||
},
|
||||
queryParams: { gitlab_url: 'https://gitlab.com' },
|
||||
staticPreview: {
|
||||
label: 'languages',
|
||||
message: '5',
|
||||
},
|
||||
documentation,
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'languages' }
|
||||
|
||||
static render({ languagesCount }) {
|
||||
return {
|
||||
message: metric(languagesCount),
|
||||
color: 'blue',
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ project, baseUrl }) {
|
||||
// https://docs.gitlab.com/ee/api/projects.html#languages
|
||||
return super.fetch({
|
||||
schema,
|
||||
url: `${baseUrl}/api/v4/projects/${encodeURIComponent(
|
||||
project
|
||||
)}/languages`,
|
||||
errorMessages: errorMessagesFor('project not found'),
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ project }, { gitlab_url: baseUrl = 'https://gitlab.com' }) {
|
||||
const data = await this.fetch({
|
||||
project,
|
||||
baseUrl,
|
||||
})
|
||||
return this.constructor.render({ languagesCount: Object.keys(data).length })
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { isMetric } from '../test-validators.js'
|
||||
import { createServiceTester } from '../tester.js'
|
||||
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('language count').get('/gitlab-org/gitlab.json').expectBadge({
|
||||
label: 'languages',
|
||||
message: isMetric,
|
||||
color: 'blue',
|
||||
})
|
||||
|
||||
t.create('language count (self-managed)')
|
||||
.get('/gitlab-cn/gitlab.json?gitlab_url=https://jihulab.com')
|
||||
.expectBadge({
|
||||
label: 'languages',
|
||||
message: isMetric,
|
||||
color: 'blue',
|
||||
})
|
||||
|
||||
t.create('language count (project not found)')
|
||||
.get('/open/guoxudong.io/shields-test/do-not-exist.json')
|
||||
.expectBadge({
|
||||
label: 'languages',
|
||||
message: 'project not found',
|
||||
})
|
||||
@@ -23,9 +23,9 @@ t.create('version installs | valid: numeric version')
|
||||
})
|
||||
|
||||
t.create('version installs | valid: alphanumeric version')
|
||||
.get('/build-failure-analyzer/1.17.2-DRE3.21.json')
|
||||
.get('/build-failure-analyzer/1.17.2-DRE3.14.json')
|
||||
.expectBadge({
|
||||
label: 'installs@1.17.2-DRE3.21',
|
||||
label: 'installs@1.17.2-DRE3.14',
|
||||
message: isMetric,
|
||||
})
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ t.create('total downloads (valid)')
|
||||
})
|
||||
|
||||
t.create('total downloads (tenant)')
|
||||
.get('/vs-devcore.myget/vs-devcore/dt/MicroBuild.json')
|
||||
.get('/cefsharp.myget/cefsharp/dt/CefSharp.Common.json')
|
||||
.expectBadge({
|
||||
label: 'downloads',
|
||||
message: isMetric,
|
||||
|
||||
@@ -1,11 +1,83 @@
|
||||
import { deprecatedService } from '../index.js'
|
||||
import Joi from 'joi'
|
||||
import { starRating, metric } from '../text-formatters.js'
|
||||
import { colorScale } from '../color-formatters.js'
|
||||
import { nonNegativeInteger } from '../validators.js'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
|
||||
export default deprecatedService({
|
||||
category: 'rating',
|
||||
route: {
|
||||
const pkgReviewColor = colorScale([2, 3, 4])
|
||||
|
||||
const schema = Joi.object({
|
||||
rating: Joi.number().min(0).max(1).precision(1).required().allow(null),
|
||||
reviewsCount: nonNegativeInteger,
|
||||
}).required()
|
||||
|
||||
// Repository for this service is: https://github.com/iqubex-technologies/pkgreview.dev
|
||||
// Internally the service leverages the npms.io API (https://api.npms.io/v2)
|
||||
export default class PkgreviewRating extends BaseJsonService {
|
||||
static category = 'rating'
|
||||
|
||||
static route = {
|
||||
base: 'pkgreview',
|
||||
pattern: ':various*',
|
||||
},
|
||||
label: 'pkgreview',
|
||||
dateAdded: new Date('2022-10-07'),
|
||||
})
|
||||
pattern: ':format(rating|stars)/:pkgManager(npm)/:pkgSlug+',
|
||||
}
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'pkgreview.dev Package Ratings',
|
||||
pattern: 'rating/:pkgManager/:pkgSlug+',
|
||||
namedParams: { pkgManager: 'npm', pkgSlug: 'react' },
|
||||
staticPreview: this.render({
|
||||
format: 'rating',
|
||||
rating: 3.5,
|
||||
reviewsCount: 237,
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: 'pkgreview.dev Star Ratings',
|
||||
pattern: 'stars/:pkgManager/:pkgSlug+',
|
||||
namedParams: { pkgManager: 'npm', pkgSlug: 'react' },
|
||||
staticPreview: this.render({
|
||||
format: 'stars',
|
||||
rating: 1.5,
|
||||
reviewsCount: 200,
|
||||
}),
|
||||
},
|
||||
]
|
||||
|
||||
static render({ rating, reviewsCount, format }) {
|
||||
const message =
|
||||
format === 'rating'
|
||||
? `${+parseFloat(rating).toFixed(1)}/5 (${metric(reviewsCount)})`
|
||||
: starRating(rating)
|
||||
|
||||
return {
|
||||
message,
|
||||
label: format,
|
||||
color: pkgReviewColor(rating),
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ pkgManager, pkgSlug }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `https://pkgreview.now.sh/api/v1/${pkgManager}/${encodeURIComponent(
|
||||
pkgSlug
|
||||
)}`,
|
||||
errorMessages: {
|
||||
404: 'package not found',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ format, pkgManager, pkgSlug }) {
|
||||
const { reviewsCount, rating } = await this.fetch({
|
||||
pkgManager,
|
||||
pkgSlug,
|
||||
})
|
||||
return this.constructor.render({
|
||||
reviewsCount,
|
||||
format,
|
||||
rating: rating * 5,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
import { ServiceTester } from '../tester.js'
|
||||
import { withRegex, isStarRating } from '../test-validators.js'
|
||||
import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
export const t = new ServiceTester({
|
||||
id: 'pkgreview',
|
||||
title: 'PkgReview',
|
||||
pathPrefix: '/pkgreview',
|
||||
})
|
||||
const isRatingWithReviews = withRegex(
|
||||
/^(([0-4](.?([0-9]))?)|5)\/5?\s*\([0-9]*\)$/
|
||||
)
|
||||
|
||||
t.create('Stars Badge')
|
||||
t.create('Stars Badge renders')
|
||||
.get('/stars/npm/react.json')
|
||||
.expectBadge({ label: 'pkgreview', message: 'no longer available' })
|
||||
.expectBadge({ label: 'stars', message: isStarRating })
|
||||
|
||||
t.create('Rating Badge')
|
||||
t.create('Rating Badge renders')
|
||||
.get('/rating/npm/react.json')
|
||||
.expectBadge({ label: 'pkgreview', message: 'no longer available' })
|
||||
.expectBadge({ label: 'rating', message: isRatingWithReviews })
|
||||
|
||||
t.create('nonexistent package')
|
||||
.get('/rating/npm/ohlolweallknowthispackagewontexist.json')
|
||||
.expectBadge({
|
||||
label: 'rating',
|
||||
message: 'package not found',
|
||||
color: 'red',
|
||||
})
|
||||
|
||||
@@ -35,7 +35,7 @@ class PowershellGalleryPlatformSupport extends BaseXmlService {
|
||||
static examples = [
|
||||
{
|
||||
title: 'PowerShell Gallery',
|
||||
namedParams: { packageName: 'PackageManagement' },
|
||||
namedParams: { packageName: 'DNS.1.1.1.1' },
|
||||
staticPreview: this.render({
|
||||
platforms: ['windows', 'macos', 'linux'],
|
||||
}),
|
||||
|
||||
@@ -47,7 +47,7 @@ t.create('version (legacy redirect: vpre)')
|
||||
.get('/vpre/ACMESharp.svg')
|
||||
.expectRedirect('/powershellgallery/v/ACMESharp.svg?include_prereleases')
|
||||
|
||||
t.create('platform (valid)').get('/p/PackageManagement.json').expectBadge({
|
||||
t.create('platform (valid').get('/p/DNS.1.1.1.1.json').expectBadge({
|
||||
label: 'platform',
|
||||
message: isPlatform,
|
||||
})
|
||||
|
||||
@@ -26,7 +26,7 @@ export default class PubPoints extends BaseJsonService {
|
||||
keywords,
|
||||
documentation,
|
||||
namedParams: { packageName: 'analysis_options' },
|
||||
staticPreview: this.render({ grantedPoints: 120, maxPoints: 140 }),
|
||||
staticPreview: this.render({ grantedPoints: 120, maxPoints: 130 }),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ t.create('pub points (valid)')
|
||||
.get('/analysis_options.json')
|
||||
.expectBadge({
|
||||
label: 'points',
|
||||
message: Joi.string().regex(/^\d+\/140$/),
|
||||
message: Joi.string().regex(/^\d+\/130$/),
|
||||
})
|
||||
|
||||
t.create('pub points (not found)').get('/analysisoptions.json').expectBadge({
|
||||
|
||||
@@ -62,10 +62,7 @@ t.create('valid repo -- unregistered')
|
||||
color: COLOR_MAP.unregistered,
|
||||
})
|
||||
|
||||
t.create('invalid repo')
|
||||
.timeout(15000)
|
||||
.get('/github.com/repo/invalid-repo.json')
|
||||
.expectBadge({
|
||||
label: 'reuse',
|
||||
message: 'Not a Git repository',
|
||||
})
|
||||
t.create('invalid repo').get('/github.com/repo/invalid-repo.json').expectBadge({
|
||||
label: 'reuse',
|
||||
message: 'Not a Git repository',
|
||||
})
|
||||
|
||||
@@ -155,15 +155,6 @@ const isCustomCompactTestTotals = makeCompactTestTotalsValidator({
|
||||
skipped: '🤷',
|
||||
})
|
||||
|
||||
const isOrdinalNumber = Joi.string().regex(/^[1-9][0-9]*(ᵗʰ|ˢᵗ|ⁿᵈ|ʳᵈ)$/)
|
||||
const isOrdinalNumberDaily = Joi.string().regex(
|
||||
/^[1-9][0-9]*(ᵗʰ|ˢᵗ|ⁿᵈ|ʳᵈ) daily$/
|
||||
)
|
||||
|
||||
const isHumanized = Joi.string().regex(
|
||||
/[0-9a-z]+ (second|seconds|minute|minutes|hour|hours|day|days|month|months|year|years)/
|
||||
)
|
||||
|
||||
export {
|
||||
isSemver,
|
||||
isVPlusTripleDottedVersion,
|
||||
@@ -196,7 +187,4 @@ export {
|
||||
isCustomCompactTestTotals,
|
||||
makeTestTotalsValidator,
|
||||
makeCompactTestTotalsValidator,
|
||||
isOrdinalNumber,
|
||||
isOrdinalNumberDaily,
|
||||
isHumanized,
|
||||
}
|
||||
|
||||
@@ -124,11 +124,9 @@ function formatDate(d) {
|
||||
}
|
||||
|
||||
function formatRelativeDate(timestamp) {
|
||||
const parsedDate = dayjs.unix(parseInt(timestamp, 10))
|
||||
if (!parsedDate.isValid()) {
|
||||
return 'invalid date'
|
||||
}
|
||||
return dayjs().to(parsedDate).toLowerCase()
|
||||
return dayjs()
|
||||
.to(dayjs.unix(parseInt(timestamp, 10)))
|
||||
.toLowerCase()
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
@@ -153,11 +153,5 @@ describe('Text formatters', function () {
|
||||
.describe('when given the beginning of october')
|
||||
.expect('a month ago')
|
||||
})
|
||||
|
||||
test(formatRelativeDate, () => {
|
||||
given(9999999999999)
|
||||
.describe('when given invalid date')
|
||||
.expect('invalid date')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
import Joi from 'joi'
|
||||
import dayjs from 'dayjs'
|
||||
import calendar from 'dayjs/plugin/calendar.js'
|
||||
import duration from 'dayjs/plugin/duration.js'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime.js'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { metric as formatMetric, ordinalNumber } from '../text-formatters.js'
|
||||
dayjs.extend(calendar)
|
||||
dayjs.extend(duration)
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
const schema = Joi.object({
|
||||
Keys: Joi.alternatives(Joi.string(), Joi.number()).required(),
|
||||
Clicks: Joi.alternatives(Joi.string(), Joi.number()).required(),
|
||||
UptimeSeconds: Joi.alternatives(Joi.string(), Joi.number()).required(),
|
||||
Download: Joi.string().required(),
|
||||
Upload: Joi.string().required(),
|
||||
Ranks: Joi.object({
|
||||
Keys: Joi.string().required(),
|
||||
Clicks: Joi.string().required(),
|
||||
Download: Joi.string().required(),
|
||||
Upload: Joi.string().required(),
|
||||
Uptime: Joi.string().required(),
|
||||
}),
|
||||
}).required()
|
||||
|
||||
const queryParamSchema = Joi.object({
|
||||
rank: Joi.equal(''),
|
||||
}).required()
|
||||
|
||||
export default class WhatPulse extends BaseJsonService {
|
||||
static category = 'activity'
|
||||
static route = {
|
||||
base: 'whatpulse',
|
||||
pattern:
|
||||
':metric(keys|clicks|uptime|download|upload)/:userType(user|team)/:id',
|
||||
queryParamSchema,
|
||||
}
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'WhatPulse user metric',
|
||||
namedParams: { metric: 'keys', userType: 'user', id: '179734' },
|
||||
staticPreview: this.render({
|
||||
metric: 'keys',
|
||||
metricValue: '21G',
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: 'WhatPulse team metric - rank',
|
||||
namedParams: {
|
||||
metric: 'upload',
|
||||
userType: 'team',
|
||||
id: 'dutch power cows',
|
||||
},
|
||||
queryParams: { rank: null },
|
||||
staticPreview: this.render({
|
||||
metric: 'upload',
|
||||
metricValue: '1ˢᵗ',
|
||||
}),
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'whatpulse' }
|
||||
|
||||
static render({ metric, metricValue }) {
|
||||
return {
|
||||
label: metric,
|
||||
message: metricValue,
|
||||
color: 'informational',
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ userType, id }) {
|
||||
return await this._requestJson({
|
||||
schema,
|
||||
url: `https://api.whatpulse.org/${userType}.php?${userType}=${id}&format=json`,
|
||||
})
|
||||
}
|
||||
|
||||
toLowerKeys(obj) {
|
||||
return Object.keys(obj).reduce((accumulator, key) => {
|
||||
accumulator[key.toLowerCase()] = obj[key]
|
||||
return accumulator
|
||||
}, {})
|
||||
}
|
||||
|
||||
transform({ json, metric }, { rank }) {
|
||||
// We want to compare with lowercase keys from the WhatPulse's API.
|
||||
const jsonLowercase = this.toLowerKeys(json)
|
||||
jsonLowercase.ranks = this.toLowerKeys(json.Ranks)
|
||||
|
||||
// Just metric, no rank.
|
||||
if (rank === undefined) {
|
||||
if (metric === 'uptime') {
|
||||
return dayjs.duration(jsonLowercase.uptimeseconds, 'seconds').humanize()
|
||||
}
|
||||
|
||||
let metricValue
|
||||
|
||||
metricValue = jsonLowercase[metric]
|
||||
|
||||
if (metric === 'keys' || metric === 'clicks') {
|
||||
metricValue = formatMetric(metricValue)
|
||||
}
|
||||
|
||||
if (metric === 'upload' || metric === 'download') {
|
||||
metricValue = metricValue.replace(/([A-Za-z]+)/, ' $1')
|
||||
}
|
||||
|
||||
return metricValue
|
||||
}
|
||||
|
||||
// Rank achieved by the user/team with the given metric.
|
||||
const rankFromResp = jsonLowercase.ranks[metric]
|
||||
|
||||
return ordinalNumber(rankFromResp)
|
||||
}
|
||||
|
||||
async handle({ metric, userType, id }, { rank }) {
|
||||
const json = await this.fetch({ userType, id, metric })
|
||||
const metricValue = this.transform({ json, metric }, { rank })
|
||||
|
||||
return this.constructor.render({ metric, metricValue })
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
import { createServiceTester } from '../tester.js'
|
||||
import {
|
||||
isFileSize,
|
||||
isHumanized,
|
||||
isMetric,
|
||||
isOrdinalNumber,
|
||||
} from '../test-validators.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('WhatPulse user as user id, uptime')
|
||||
.get('/uptime/user/179734.json')
|
||||
.expectBadge({ label: 'uptime', message: isHumanized })
|
||||
|
||||
t.create('WhatPulse user as user name, keys')
|
||||
.get('/keys/user/jerone.json')
|
||||
.expectBadge({ label: 'keys', message: isMetric })
|
||||
|
||||
t.create('WhatPulse team as team id, clicks')
|
||||
.get('/clicks/team/1295.json')
|
||||
.expectBadge({ label: 'clicks', message: isMetric })
|
||||
|
||||
t.create('WhatPulse team as team id, download')
|
||||
.get('/download/team/1295.json')
|
||||
.expectBadge({ label: 'download', message: isFileSize })
|
||||
|
||||
t.create('WhatPulse team as team id, upload')
|
||||
.get('/upload/team/1295.json')
|
||||
.expectBadge({ label: 'upload', message: isFileSize })
|
||||
|
||||
t.create('WhatPulse team as team name, keys - from Ranks')
|
||||
.get('/keys/team/dutch power cows.json?rank')
|
||||
.expectBadge({ label: 'keys', message: isOrdinalNumber })
|
||||
|
||||
t.create(
|
||||
'WhatPulse invalid metric name (not one of the options from the modal`s dropdown)'
|
||||
)
|
||||
.get('/UpTIMe/user/jerone.json')
|
||||
.expectBadge({ label: '404', message: 'badge not found' })
|
||||
|
||||
t.create('WhatPulse incorrect user name')
|
||||
.get('/uptime/user/NonExistentUsername.json')
|
||||
.expectBadge({ label: 'whatpulse', message: 'invalid response data' })
|
||||
@@ -190,22 +190,6 @@ t.create('Plugin Required PHP Version')
|
||||
|
||||
t.create('Plugin Required PHP Version (Not Set)')
|
||||
.get('/plugin/required-php/akismet.json')
|
||||
.intercept(nock =>
|
||||
nock('https://api.wordpress.org')
|
||||
.get('/plugins/info/1.2/')
|
||||
.query(mockedQuerySelector)
|
||||
.reply(200, {
|
||||
version: '1.2',
|
||||
rating: 80,
|
||||
num_ratings: 100,
|
||||
downloaded: 100,
|
||||
active_installs: 100,
|
||||
requires: false,
|
||||
tested: '4.0.0',
|
||||
last_updated: '2020-01-01 7:21am GMT',
|
||||
requires_php: false,
|
||||
})
|
||||
)
|
||||
.expectBadge({
|
||||
label: 'php',
|
||||
message: 'not set for this plugin',
|
||||
|
||||
Reference in New Issue
Block a user