Compare commits

...

86 Commits

Author SHA1 Message Date
chris48s
ae1f3c3710 do nothing 2023-04-11 19:27:40 +01:00
chris48s
148b51d554 Export OpenAPI definitions from service examples; affects [dynamic endpoint static] (#8966)
* WIP export OpenAPI definitions from service examples

* allow services to optionally define an OpenApi Paths Object instead of examples

* make use of param descriptions and required query params

* convert other 'core' services to declare openApi..

..instead of examples

* tweak descriptions for standard query params

* move stuff around, add a high-level integration test for category2openapi

* update simple-icons text refs #9054

* remove legacy param names
2023-04-11 18:37:16 +01:00
chris48s
ba4a5619ec fix markdown summary if there are pending tests (#9068) 2023-04-10 10:19:16 +01:00
LitoMore
95ef751096 Update the hint of simple-icons (#9054)
* Update the hint of simple-icons

* copy edits

---------

Co-authored-by: chris48s <git@chris-shaw.dev>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-04-08 18:32:51 +00:00
dependabot[bot]
7cb0b67af5 chore(deps): bump simple-icons from 8.8.0 to 8.9.0 (#9063)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 8.8.0 to 8.9.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/compare/8.8.0...8.9.0)

---
updated-dependencies:
- dependency-name: simple-icons
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 20:23:50 +00:00
dependabot[bot]
54a66ef160 chore(deps): bump @sentry/node from 7.46.0 to 7.47.0 (#9060)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.46.0 to 7.47.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.46.0...7.47.0)

---
updated-dependencies:
- dependency-name: "@sentry/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-04-07 20:16:20 +00:00
dependabot[bot]
f0c3a5c363 chore(deps-dev): bump @typescript-eslint/eslint-plugin (#9058)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.57.0 to 5.57.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.57.1/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-04-07 20:10:16 +00:00
dependabot[bot]
8d0ed2c8c0 chore(deps): bump glob from 9.3.2 to 9.3.4 (#9059)
Bumps [glob](https://github.com/isaacs/node-glob) from 9.3.2 to 9.3.4.
- [Release notes](https://github.com/isaacs/node-glob/releases)
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v9.3.2...v9.3.4)

---
updated-dependencies:
- dependency-name: glob
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-04-07 20:04:55 +00:00
dependabot[bot]
9c4e5682f3 chore(deps-dev): bump eslint-plugin-sort-class-members (#9061)
Bumps [eslint-plugin-sort-class-members](https://github.com/bryanrsmith/eslint-plugin-sort-class-members) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/bryanrsmith/eslint-plugin-sort-class-members/releases)
- [Commits](https://github.com/bryanrsmith/eslint-plugin-sort-class-members/compare/v1.16.0...v1.17.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-sort-class-members
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 20:57:20 +01:00
dependabot[bot]
b22c554bc8 chore(deps-dev): bump lint-staged from 13.2.0 to 13.2.1 (#9057)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 13.2.0 to 13.2.1.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v13.2.0...v13.2.1)

---
updated-dependencies:
- dependency-name: lint-staged
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 20:50:23 +01:00
github-actions[bot]
74c7b062dd Changelog for Release server-2023-04-02 (#9052)
* Update Changelog

* Update CHANGELOG.md

---------

Co-authored-by: release[bot] <actions@users.noreply.github.com>
Co-authored-by: chris48s <chris48s@users.noreply.github.com>
2023-04-02 19:43:22 +01:00
dependabot[bot]
f5876c3ec4 chore(deps-dev): bump typescript from 5.0.2 to 5.0.3 (#9047)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.0.2 to 5.0.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/commits)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-01 11:07:11 +00:00
dependabot[bot]
3bf2246788 chore(deps-dev): bump @babel/core from 7.21.3 to 7.21.4 (#9043)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.21.3 to 7.21.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.21.4/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-04-01 10:44:53 +00:00
dependabot[bot]
0d8f35b4ef chore(deps-dev): bump concurrently from 7.6.0 to 8.0.1 (#9041)
Bumps [concurrently](https://github.com/open-cli-tools/concurrently) from 7.6.0 to 8.0.1.
- [Release notes](https://github.com/open-cli-tools/concurrently/releases)
- [Commits](https://github.com/open-cli-tools/concurrently/compare/v7.6.0...v8.0.1)

---
updated-dependencies:
- dependency-name: concurrently
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-01 10:40:20 +00:00
dependabot[bot]
9d57b61811 chore(deps-dev): bump @typescript-eslint/eslint-plugin (#9045)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.56.0 to 5.57.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.57.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-31 21:28:45 +00:00
dependabot[bot]
3cb76e78be chore(deps-dev): bump tsd from 0.28.0 to 0.28.1 (#9040)
Bumps [tsd](https://github.com/SamVerschueren/tsd) from 0.28.0 to 0.28.1.
- [Release notes](https://github.com/SamVerschueren/tsd/releases)
- [Commits](https://github.com/SamVerschueren/tsd/compare/v0.28.0...v0.28.1)

---
updated-dependencies:
- dependency-name: tsd
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-31 21:22:47 +00:00
dependabot[bot]
138fdbee81 chore(deps-dev): bump cypress from 12.8.1 to 12.9.0 (#9039)
Bumps [cypress](https://github.com/cypress-io/cypress) from 12.8.1 to 12.9.0.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/cypress-io/cypress/compare/v12.8.1...v12.9.0)

---
updated-dependencies:
- dependency-name: cypress
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-31 22:14:03 +01:00
dependabot[bot]
2cb5363c84 chore(deps-dev): bump eslint-plugin-jsdoc from 40.1.0 to 40.1.1 (#9042)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 40.1.0 to 40.1.1.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v40.1.0...v40.1.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-31 19:18:08 +00:00
dependabot[bot]
d248e9c892 chore(deps): bump @renovatebot/ruby-semver from 2.1.9 to 2.1.10 (#9048)
Bumps [@renovatebot/ruby-semver](https://github.com/renovatebot/ruby-semver) from 2.1.9 to 2.1.10.
- [Release notes](https://github.com/renovatebot/ruby-semver/releases)
- [Changelog](https://github.com/renovatebot/ruby-semver/blob/main/.releaserc.json)
- [Commits](https://github.com/renovatebot/ruby-semver/compare/2.1.9...2.1.10)

---
updated-dependencies:
- dependency-name: "@renovatebot/ruby-semver"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-31 20:10:17 +01:00
dependabot[bot]
0c77a064bd chore(deps-dev): bump sinon from 15.0.2 to 15.0.3 (#9038)
Bumps [sinon](https://github.com/sinonjs/sinon) from 15.0.2 to 15.0.3.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v15.0.2...v15.0.3)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-31 18:11:17 +00:00
dependabot[bot]
b5d07f5a96 chore(deps): bump @sentry/node from 7.45.0 to 7.46.0 (#9046)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.45.0 to 7.46.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.45.0...7.46.0)

---
updated-dependencies:
- dependency-name: "@sentry/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-31 17:58:28 +00:00
dependabot[bot]
d5a74d5d21 chore(deps-dev): bump eslint-plugin-cypress from 2.12.1 to 2.13.2 (#9049)
Bumps [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress) from 2.12.1 to 2.13.2.
- [Release notes](https://github.com/cypress-io/eslint-plugin-cypress/releases)
- [Commits](https://github.com/cypress-io/eslint-plugin-cypress/compare/v2.12.1...v2.13.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-cypress
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-31 18:50:42 +01:00
Yukai Chou
6deeadcfe1 [CTAN] fallback to date if version is empty (#9036)
* [CTAN] version: Fallback to date if version is empty

* Fix importing of `InvalidResponse`

* Satisfy prettier manually

* Format code using a global prettier

* more readability

* use `joi` schema directly

* make `version.date` also `required()`

* import `Joi`

* add required `date` entry for tests

* examples don't need `date` entry
2023-03-29 19:46:40 +00:00
chris48s
82dddab90f update docker hosting docs (#9018)
* update docs: DockerHub --> GHCR

* hey bro, you've got options

---------

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-28 19:21:47 +01:00
Matthew Mirvish
0e0ac8fe60 [JenkinsCoverage] Update Jenkins Code Coverage API for new plugin version (#9010)
* Update Jenkins Code Coverage API for new plugin version

Recently, the Jenkins Code Coverage API plugin re-added its external
API, but changed the format. This updates the jenkins service to
accomodate the new API.

* Update coverage API test url

* Re-introduce old badge format as apiv1 and add redirectors

* Mock coverage apiv1 with historical result

* format mock response as object

---------

Co-authored-by: chris48s <git@chris-shaw.dev>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-25 18:24:53 +00:00
Yukai Chou
4b847b98c2 Update to [CTAN] API version 2.0 (#9016)
* Update to CTAN API version 2.0

also use https protocol for CTAN tests

see https://www.ctan.org/help/json/2.0/pkg

* Add a version validator for CTAN only

The latest CTAN package `novel` is versioned v1.81a.

---------

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-25 18:18:32 +00:00
dependabot[bot]
793b2480e5 chore(deps): bump simple-icons from 8.7.0 to 8.8.0 (#9029)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 8.7.0 to 8.8.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/compare/8.7.0...8.8.0)

---
updated-dependencies:
- dependency-name: simple-icons
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-25 16:04:13 +00:00
dependabot[bot]
029b141726 chore(deps): bump joi from 17.8.4 to 17.9.1 (#9035)
Bumps [joi](https://github.com/hapijs/joi) from 17.8.4 to 17.9.1.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Commits](https://github.com/hapijs/joi/compare/v17.8.4...v17.9.1)

---
updated-dependencies:
- dependency-name: joi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-25 15:58:05 +00:00
dependabot[bot]
009bc74109 chore(deps-dev): bump nodemon from 2.0.21 to 2.0.22 (#9024)
Bumps [nodemon](https://github.com/remy/nodemon) from 2.0.21 to 2.0.22.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v2.0.21...v2.0.22)

---
updated-dependencies:
- dependency-name: nodemon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-25 15:52:36 +00:00
dependabot[bot]
63aa80db96 chore(deps-dev): bump @typescript-eslint/eslint-plugin (#9032)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.55.0 to 5.56.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.56.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-25 12:44:54 +00:00
dependabot[bot]
0356aba535 chore(deps): bump @sentry/node from 7.43.0 to 7.45.0 (#9026)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.43.0 to 7.45.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.43.0...7.45.0)

---
updated-dependencies:
- dependency-name: "@sentry/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-25 11:35:28 +00:00
dependabot[bot]
18216e8baa chore(deps-dev): bump open-cli from 7.1.0 to 7.2.0 (#9031)
Bumps [open-cli](https://github.com/sindresorhus/open-cli) from 7.1.0 to 7.2.0.
- [Release notes](https://github.com/sindresorhus/open-cli/releases)
- [Commits](https://github.com/sindresorhus/open-cli/compare/v7.1.0...v7.2.0)

---
updated-dependencies:
- dependency-name: open-cli
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-25 11:28:09 +00:00
dependabot[bot]
af664e8d7f chore(deps): bump glob from 9.3.0 to 9.3.2 (#9030)
Bumps [glob](https://github.com/isaacs/node-glob) from 9.3.0 to 9.3.2.
- [Release notes](https://github.com/isaacs/node-glob/releases)
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v9.3.0...v9.3.2)

---
updated-dependencies:
- dependency-name: glob
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-25 11:18:57 +00:00
dependabot[bot]
e35f2ee1ad chore(deps-dev): bump eslint-plugin-jsdoc from 40.0.3 to 40.1.0 (#9021)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 40.0.3 to 40.1.0.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v40.0.3...v40.1.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-25 11:10:59 +00:00
dependabot[bot]
d242d8045b chore(deps-dev): bump tsd from 0.27.0 to 0.28.0 (#9027)
Bumps [tsd](https://github.com/SamVerschueren/tsd) from 0.27.0 to 0.28.0.
- [Release notes](https://github.com/SamVerschueren/tsd/releases)
- [Commits](https://github.com/SamVerschueren/tsd/compare/v0.27.0...v0.28.0)

---
updated-dependencies:
- dependency-name: tsd
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-24 20:18:12 +00:00
dependabot[bot]
732f783b22 chore(deps-dev): bump rimraf from 4.4.0 to 4.4.1 (#9023)
Bumps [rimraf](https://github.com/isaacs/rimraf) from 4.4.0 to 4.4.1.
- [Release notes](https://github.com/isaacs/rimraf/releases)
- [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/rimraf/compare/v4.4.0...v4.4.1)

---
updated-dependencies:
- dependency-name: rimraf
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-24 19:56:07 +00:00
dependabot[bot]
ca923b2c12 chore(deps-dev): bump prettier from 2.8.4 to 2.8.7 (#9033)
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.4 to 2.8.7.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.4...2.8.7)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-24 19:46:44 +00:00
dependabot[bot]
b0f8416dd0 chore(deps-dev): bump eslint-config-prettier from 8.7.0 to 8.8.0 (#9034)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.7.0 to 8.8.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.7.0...v8.8.0)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-24 19:35:38 +00:00
chris48s
0556f02fae Fix tests for [dynamic endpoint] services (#9015)
* fix endpoint tests

* fix dyanmic json tests
2023-03-23 17:53:49 -05:00
dependabot[bot]
19ec4a3c92 chore(deps-dev): bump typescript from 4.9.5 to 5.0.2 (#9003)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.9.5 to 5.0.2.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.9.5...v5.0.2)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-18 10:04:36 +00:00
dependabot[bot]
aafb26b8f7 chore(deps): bump joi from 17.8.3 to 17.8.4 (#9006)
Bumps [joi](https://github.com/hapijs/joi) from 17.8.3 to 17.8.4.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Commits](https://github.com/hapijs/joi/compare/v17.8.3...v17.8.4)

---
updated-dependencies:
- dependency-name: joi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-18 09:56:13 +00:00
dependabot[bot]
c1ff413c57 chore(deps-dev): bump node-mocks-http from 1.12.1 to 1.12.2 (#9000)
Bumps [node-mocks-http](https://github.com/howardabrams/node-mocks-http) from 1.12.1 to 1.12.2.
- [Release notes](https://github.com/howardabrams/node-mocks-http/releases)
- [Changelog](https://github.com/howardabrams/node-mocks-http/blob/master/HISTORY.md)
- [Commits](https://github.com/howardabrams/node-mocks-http/compare/v1.12.1...v1.12.2)

---
updated-dependencies:
- dependency-name: node-mocks-http
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-18 09:50:26 +00:00
dependabot[bot]
bc12b1abc8 chore(deps-dev): bump @typescript-eslint/parser from 5.46.0 to 5.55.0 (#9005)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.46.0 to 5.55.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.55.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-18 09:43:51 +00:00
dependabot[bot]
d3256100d5 chore(deps-dev): bump cypress from 12.7.0 to 12.8.1 (#8999)
Bumps [cypress](https://github.com/cypress-io/cypress) from 12.7.0 to 12.8.1.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/cypress-io/cypress/compare/v12.7.0...v12.8.1)

---
updated-dependencies:
- dependency-name: cypress
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-18 09:17:49 +00:00
dependabot[bot]
c826c7017b chore(deps-dev): bump styled-components from 5.3.8 to 5.3.9 (#8995)
Bumps [styled-components](https://github.com/styled-components/styled-components) from 5.3.8 to 5.3.9.
- [Release notes](https://github.com/styled-components/styled-components/releases)
- [Commits](https://github.com/styled-components/styled-components/compare/v5.3.8...v5.3.9)

---
updated-dependencies:
- dependency-name: styled-components
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-17 21:22:49 +00:00
dependabot[bot]
73d5b95fbd chore(deps): bump simple-icons from 8.6.0 to 8.7.0 (#8998)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 8.6.0 to 8.7.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/compare/8.6.0...8.7.0)

---
updated-dependencies:
- dependency-name: simple-icons
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-17 21:14:14 +00:00
dependabot[bot]
a284857e86 chore(deps-dev): bump @babel/core from 7.21.0 to 7.21.3 (#8996)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.21.0 to 7.21.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.21.3/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-17 21:01:30 +00:00
dependabot[bot]
38cf3ecc42 chore(deps-dev): bump sinon from 15.0.1 to 15.0.2 (#8994)
Bumps [sinon](https://github.com/sinonjs/sinon) from 15.0.1 to 15.0.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v15.0.1...v15.0.2)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-17 20:52:36 +00:00
dependabot[bot]
540bf96a6b chore(deps-dev): bump @typescript-eslint/eslint-plugin (#9007)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.54.0 to 5.55.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.55.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-17 20:44:40 +00:00
chris48s
5b44341e1b log into the right registry (#9009) 2023-03-17 20:31:57 +00:00
chris48s
0dcfa76c53 push images to both GHCR and DockerHub (#9008) 2023-03-17 20:21:44 +00:00
dependabot[bot]
0be37ada2d chore(deps): bump @sentry/node from 7.42.0 to 7.43.0 (#9002)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.42.0 to 7.43.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.42.0...7.43.0)

---
updated-dependencies:
- dependency-name: "@sentry/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-17 19:44:36 +00:00
dependabot[bot]
e03cd54bd6 chore(deps): bump glob from 9.2.1 to 9.3.0 (#8997)
Bumps [glob](https://github.com/isaacs/node-glob) from 9.2.1 to 9.3.0.
- [Release notes](https://github.com/isaacs/node-glob/releases)
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v9.2.1...v9.3.0)

---
updated-dependencies:
- dependency-name: glob
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-17 19:31:56 +00:00
dependabot[bot]
37756e3d06 chore(deps-dev): bump eslint-plugin-jsdoc from 40.0.1 to 40.0.3 (#9004)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 40.0.1 to 40.0.3.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v40.0.1...v40.0.3)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-17 19:14:11 +00:00
dependabot[bot]
527c9cf561 chore(deps-dev): bump deepmerge from 4.3.0 to 4.3.1 (#9001)
Bumps [deepmerge](https://github.com/TehShrike/deepmerge) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/TehShrike/deepmerge/releases)
- [Changelog](https://github.com/TehShrike/deepmerge/blob/master/changelog.md)
- [Commits](https://github.com/TehShrike/deepmerge/compare/v4.3.0...v4.3.1)

---
updated-dependencies:
- dependency-name: deepmerge
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-17 19:05:25 +00:00
dependabot[bot]
576b0b582f chore(deps): bump webpack from 5.62.1 to 5.76.1 (#8990)
Bumps [webpack](https://github.com/webpack/webpack) from 5.62.1 to 5.76.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.62.1...v5.76.1)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-14 19:19:31 +00:00
chris48s
46cab5f57b handle missing statistics array in [VisualStudioMarketplace] badges (#8985)
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-13 18:42:00 +00:00
dependabot[bot]
de39ee7aae chore(deps): bump got from 12.5.3 to 12.6.0 (#8974)
Bumps [got](https://github.com/sindresorhus/got) from 12.5.3 to 12.6.0.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v12.5.3...v12.6.0)

---
updated-dependencies:
- dependency-name: got
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-11 12:32:47 +00:00
dependabot[bot]
ad25649d07 chore(deps): bump prom-client from 14.1.1 to 14.2.0 (#8975)
Bumps [prom-client](https://github.com/siimon/prom-client) from 14.1.1 to 14.2.0.
- [Release notes](https://github.com/siimon/prom-client/releases)
- [Changelog](https://github.com/siimon/prom-client/blob/master/CHANGELOG.md)
- [Commits](https://github.com/siimon/prom-client/compare/v14.1.1...v14.2.0)

---
updated-dependencies:
- dependency-name: prom-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-11 11:33:11 +00:00
dependabot[bot]
c88a822ce4 chore(deps-dev): bump tsd from 0.25.0 to 0.27.0 (#8978)
Bumps [tsd](https://github.com/SamVerschueren/tsd) from 0.25.0 to 0.27.0.
- [Release notes](https://github.com/SamVerschueren/tsd/releases)
- [Commits](https://github.com/SamVerschueren/tsd/compare/v0.25.0...v0.27.0)

---
updated-dependencies:
- dependency-name: tsd
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-11 11:24:37 +00:00
dependabot[bot]
7c79eb1417 chore(deps-dev): bump lint-staged from 13.1.2 to 13.2.0 (#8980)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 13.1.2 to 13.2.0.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v13.1.2...v13.2.0)

---
updated-dependencies:
- dependency-name: lint-staged
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-11 11:19:20 +00:00
dependabot[bot]
fc4ef6326a chore(deps): bump qs from 6.11.0 to 6.11.1 (#8984)
Bumps [qs](https://github.com/ljharb/qs) from 6.11.0 to 6.11.1.
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.11.0...v6.11.1)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-11 11:09:14 +00:00
dependabot[bot]
e8e220b8cf chore(deps): bump @renovatebot/ruby-semver from 2.1.8 to 2.1.9 (#8979)
Bumps [@renovatebot/ruby-semver](https://github.com/renovatebot/ruby-semver) from 2.1.8 to 2.1.9.
- [Release notes](https://github.com/renovatebot/ruby-semver/releases)
- [Changelog](https://github.com/renovatebot/ruby-semver/blob/main/.releaserc.json)
- [Commits](https://github.com/renovatebot/ruby-semver/compare/2.1.8...2.1.9)

---
updated-dependencies:
- dependency-name: "@renovatebot/ruby-semver"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-11 11:02:21 +00:00
dependabot[bot]
2fe650fbec chore(deps-dev): bump eslint-config-prettier from 8.6.0 to 8.7.0 (#8973)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.6.0 to 8.7.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.6.0...v8.7.0)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-10 19:40:02 -06:00
dependabot[bot]
6cbd4cb253 chore(deps-dev): bump rimraf from 4.2.0 to 4.4.0 (#8982)
Bumps [rimraf](https://github.com/isaacs/rimraf) from 4.2.0 to 4.4.0.
- [Release notes](https://github.com/isaacs/rimraf/releases)
- [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/rimraf/compare/v4.2.0...v4.4.0)

---
updated-dependencies:
- dependency-name: rimraf
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-10 21:19:18 +00:00
dependabot[bot]
459019803c chore(deps): bump pg from 8.9.0 to 8.10.0 (#8981)
Bumps [pg](https://github.com/brianc/node-postgres/tree/HEAD/packages/pg) from 8.9.0 to 8.10.0.
- [Release notes](https://github.com/brianc/node-postgres/releases)
- [Changelog](https://github.com/brianc/node-postgres/blob/master/CHANGELOG.md)
- [Commits](https://github.com/brianc/node-postgres/commits/pg@8.10.0/packages/pg)

---
updated-dependencies:
- dependency-name: pg
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-10 21:08:13 +00:00
dependabot[bot]
bcde955e30 chore(deps): bump @sentry/node from 7.40.0 to 7.42.0 (#8977)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.40.0 to 7.42.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.40.0...7.42.0)

---
updated-dependencies:
- dependency-name: "@sentry/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-10 20:57:35 +00:00
Damien Sorel
eb969fd442 [Netlify] upgrade colors for SVG parsing (#8971)
Closes #8970
2023-03-09 19:28:08 +00:00
chris48s
2856c0e1a3 adjust route for [npmsio] badges (#8967)
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-07 05:44:25 +00:00
chris48s
fab3fd7a93 sort service path matches (#8968) 2023-03-06 15:58:16 +00:00
dependabot[bot]
a5480d5a8c chore(deps): bump glob from 8.1.0 to 9.2.1 (#8952)
* chore(deps): bump glob from 8.1.0 to 9.2.1

Bumps [glob](https://github.com/isaacs/node-glob) from 8.1.0 to 9.2.1.
- [Release notes](https://github.com/isaacs/node-glob/releases)
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v8.1.0...v9.2.1)

---
updated-dependencies:
- dependency-name: glob
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* update glob usage

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: chris48s <git@chris-shaw.dev>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-06 12:09:48 +00:00
Nicolas Jakob
4a5bf538ff Fix [Vcpkg] version service for different version fields (#8945)
* Fix [Vcpkg] version service for different version fields

* Use match one to enforce a single alternative

* Mock different version field test cases

* Extract version field parsing as separate helper

---------

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-04 20:40:22 +00:00
dependabot[bot]
f55a655203 chore(deps-dev): bump start-server-and-test from 1.15.4 to 2.0.0 (#8964)
Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.15.4 to 2.0.0.
- [Release notes](https://github.com/bahmutov/start-server-and-test/releases)
- [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.15.4...v2.0.0)

---
updated-dependencies:
- dependency-name: start-server-and-test
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-04 20:19:30 +00:00
dependabot[bot]
02c7486fed chore(deps-dev): bump styled-components from 5.3.6 to 5.3.8 (#8954)
Bumps [styled-components](https://github.com/styled-components/styled-components) from 5.3.6 to 5.3.8.
- [Release notes](https://github.com/styled-components/styled-components/releases)
- [Commits](https://github.com/styled-components/styled-components/compare/v5.3.6...v5.3.8)

---
updated-dependencies:
- dependency-name: styled-components
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-04 20:06:13 +00:00
dependabot[bot]
ab59b6b4fc chore(deps-dev): bump danger from 11.2.3 to 11.2.4 (#8953)
Bumps [danger](https://github.com/danger/danger-js) from 11.2.3 to 11.2.4.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/11.2.3...11.2.4)

---
updated-dependencies:
- dependency-name: danger
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-04 19:54:38 +00:00
dependabot[bot]
227abb4d83 chore(deps-dev): bump nodemon from 2.0.20 to 2.0.21 (#8960)
Bumps [nodemon](https://github.com/remy/nodemon) from 2.0.20 to 2.0.21.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v2.0.20...v2.0.21)

---
updated-dependencies:
- dependency-name: nodemon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-04 19:50:02 +00:00
chris48s
ab51c88d94 update docs following token pool changes (#8933)
* update docs following token pool changes

* Update CONTRIBUTING.md

Co-authored-by: Caleb Cartwright <calebcartwright@users.noreply.github.com>

---------

Co-authored-by: Caleb Cartwright <calebcartwright@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-04 19:44:08 +00:00
dependabot[bot]
b9ef8c6003 chore(deps): bump fast-xml-parser from 4.1.2 to 4.1.3 (#8963)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 4.1.2 to 4.1.3.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.1.2...v4.1.3)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-04 19:35:30 +00:00
dependabot[bot]
b746a1d2ef chore(deps-dev): bump cypress from 12.6.0 to 12.7.0 (#8965)
Bumps [cypress](https://github.com/cypress-io/cypress) from 12.6.0 to 12.7.0.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/cypress-io/cypress/compare/v12.6.0...v12.7.0)

---
updated-dependencies:
- dependency-name: cypress
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-04 19:25:31 +00:00
chris48s
565139660d only try to close pool if one exists (#8947)
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-04 17:05:38 +00:00
dependabot[bot]
549731421a chore(deps): bump @sentry/node from 7.38.0 to 7.40.0 (#8958)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 7.38.0 to 7.40.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.38.0...7.40.0)

---
updated-dependencies:
- dependency-name: "@sentry/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-04 10:47:04 -06:00
dependabot[bot]
deb0debc17 chore(deps-dev): bump eslint-plugin-jsdoc from 40.0.0 to 40.0.1 (#8956)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 40.0.0 to 40.0.1.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v40.0.0...v40.0.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-04 14:26:55 +00:00
dependabot[bot]
ba34ebac67 chore(deps-dev): bump @typescript-eslint/eslint-plugin (#8955)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.53.0 to 5.54.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.54.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-04 14:20:20 +00:00
dependabot[bot]
60ab3db855 chore(deps): bump simple-icons from 8.5.0 to 8.6.0 (#8957)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 8.5.0 to 8.6.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/compare/8.5.0...8.6.0)

---
updated-dependencies:
- dependency-name: simple-icons
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-03 22:18:44 -06:00
dependabot[bot]
e00f0c33bc chore(deps-dev): bump rimraf from 4.1.2 to 4.2.0 (#8961)
Bumps [rimraf](https://github.com/isaacs/rimraf) from 4.1.2 to 4.2.0.
- [Release notes](https://github.com/isaacs/rimraf/releases)
- [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/rimraf/compare/v4.1.2...v4.2.0)

---
updated-dependencies:
- dependency-name: rimraf
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-03 16:58:52 -06:00
chris48s
26bf69cfe7 misc minor fixes to [githubsize node pypi] (#8946)
* fix some params incorrectly marked as optional

all of these are really required

* make '@' part of the param (not route) for scoped packages

* minor HTML tweaks to sonar help

---------

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2023-03-01 20:24:41 +00:00
52 changed files with 3600 additions and 1442 deletions

View File

@@ -22,6 +22,6 @@ jobs:
with:
context: .
push: false
tags: shieldsio/shields:pr-validation
tags: ghcr.io/badges/shields:pr-validation
build-args: |
version=${{ env.SHORT_SHA }}

View File

@@ -6,6 +6,7 @@ on:
permissions:
contents: write
packages: write
jobs:
create-release:
@@ -52,3 +53,19 @@ jobs:
tags: shieldsio/shields:server-${{ steps.date.outputs.date }}
build-args: |
version=server-${{ steps.date.outputs.date }}
- name: Login to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push snapshot release to GHCR
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ghcr.io/badges/shields:server-${{ steps.date.outputs.date }}
build-args: |
version=server-${{ steps.date.outputs.date }}

View File

@@ -4,6 +4,9 @@ on:
branches:
- master
permissions:
packages: write
jobs:
publish-docker-next:
runs-on: ubuntu-latest
@@ -25,7 +28,7 @@ jobs:
- name: Set Git Short SHA
run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: Build and push
- name: Build and push to DockerHub
uses: docker/build-push-action@v4
with:
context: .
@@ -33,3 +36,19 @@ jobs:
tags: shieldsio/shields:next
build-args: |
version=${{ env.SHORT_SHA }}
- name: Login to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push to GHCR
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ghcr.io/badges/shields:next
build-args: |
version=${{ env.SHORT_SHA }}

1
.gitignore vendored
View File

@@ -96,6 +96,7 @@ typings/
badge-examples.json
supported-features.json
service-definitions.yml
frontend/categories/*.yaml
# Local runtime configuration.
/config/local*.yml

View File

@@ -4,6 +4,18 @@ Note: this changelog is for the shields.io server. The changelog for the badge-m
---
## server-2023-04-02
- [JenkinsCoverage] Update Jenkins Code Coverage API for new plugin version [#9010](https://github.com/badges/shields/issues/9010)
- [CTAN] fallback to date if version is empty [#9036](https://github.com/badges/shields/issues/9036)
- Update to [CTAN] API version 2.0 [#9016](https://github.com/badges/shields/issues/9016)
- handle missing statistics array in [VisualStudioMarketplace] badges [#8985](https://github.com/badges/shields/issues/8985)
- [Netlify] upgrade colors for SVG parsing [#8971](https://github.com/badges/shields/issues/8971)
- Fix [Vcpkg] version service for different version fields [#8945](https://github.com/badges/shields/issues/8945)
- only try to close pool if one exists [#8947](https://github.com/badges/shields/issues/8947)
- misc minor fixes to [githubsize node pypi] [#8946](https://github.com/badges/shields/issues/8946)
- Dependency updates
## server-2023-03-01
**Deprecation:** For users who need to maintain a Github Token pool, storage has been provided via the `RedisTokenPersistence` and `REDIS_URL` settings. As of this release, the `RedisTokenPersistence` backend is now deprecated and will be removed in a future release. If you are using this feature, you will need to migrate to using the `SQLTokenPersistence` backend for storage and provide a postgres connection string via the `POSTGRES_URL` setting. [#8922](https://github.com/badges/shields/issues/8922)

View File

@@ -134,9 +134,20 @@ 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.
Use `brew install redis`, `yum install redis`, etc. The test runner will
start the server automatically.
The integration tests are not run by default. For most contributions it is OK to skip these unless you're working directly on the code for storing the GitHub token pool in postgres/redis.
To run the integration tests:
- You must have Redis installed and in your PATH. Use `brew install redis`, `apt-get install redis`, etc. The test runner will start the server automatically.
- You must also have PostgreSQL installed. Use `brew install postgresql`, `apt-get install postgresql`, etc.
- Set a connection string either with an env var `POSTGRES_URL=postgresql://user:pass@127.0.0.1:5432/db_name` or by using
```yaml
private:
postgres_url: 'postgresql://user:pass@127.0.0.1:5432/db_name'
```
in a yaml config file.
- Run `npm run migrate up` to apply DB migrations
- Run `npm run test:integration` to run the tests
[service-tests]: https://github.com/badges/shields/blob/master/doc/service-tests.md

View File

@@ -140,6 +140,15 @@ class BaseService {
*/
static examples = []
/**
* Optional: an OpenAPI Paths Object describing this service's
* route or routes in OpenAPI format.
*
* @see https://swagger.io/specification/#paths-object
* @abstract
*/
static openApi = undefined
static get _cacheLength() {
const cacheLengths = {
build: 30,
@@ -183,7 +192,7 @@ class BaseService {
}
static getDefinition() {
const { category, name, isDeprecated } = this
const { category, name, isDeprecated, openApi } = this
const { base, format, pattern } = this.route
const queryParams = getQueryParamNames(this.route)
@@ -200,7 +209,7 @@ class BaseService {
route = undefined
}
const result = { category, name, isDeprecated, route, examples }
const result = { category, name, isDeprecated, route, examples, openApi }
assertValidServiceDefinition(result, `getDefinition() for ${this.name}`)

View File

@@ -129,6 +129,7 @@ function transformExample(inExample, index, ServiceClass) {
ServiceClass
)
const category = categories.find(c => c.id === ServiceClass.category)
return {
title,
example: {
@@ -146,9 +147,7 @@ function transformExample(inExample, index, ServiceClass) {
style: style === 'flat' ? undefined : style,
namedLogo,
},
keywords: keywords.concat(
categories.find(c => c.id === ServiceClass.category).keywords
),
keywords: category ? keywords.concat(category.keywords) : keywords,
documentation: documentation ? { __html: documentation } : undefined,
}
}

View File

@@ -1,6 +1,6 @@
import path from 'path'
import { fileURLToPath } from 'url'
import glob from 'glob'
import { globSync } from 'glob'
import countBy from 'lodash.countby'
import categories from '../../services/categories.js'
import BaseService from './base.js'
@@ -28,7 +28,7 @@ class InvalidService extends Error {
}
function getServicePaths(pattern) {
return glob.sync(toUnixPath(path.join(serviceDir, '**', pattern)))
return globSync(toUnixPath(path.join(serviceDir, '**', pattern))).sort()
}
async function loadServiceClasses(servicePaths) {
@@ -53,8 +53,8 @@ async function loadServiceClasses(servicePaths) {
if (serviceClass && serviceClass.prototype instanceof BaseService) {
// Decorate each service class with the directory that contains it.
serviceClass.serviceFamily = servicePath
.replace(toUnixPath(serviceDir), '')
.split('/')[1]
.replace(serviceDir, '')
.split(path.sep)[1]
serviceClass.validateDefinition()
return serviceClasses.push(serviceClass)
}

View File

@@ -0,0 +1,335 @@
const baseUrl = process.env.BASE_URL || 'https://img.shields.io'
const globalParamRefs = [
{ $ref: '#/components/parameters/style' },
{ $ref: '#/components/parameters/logo' },
{ $ref: '#/components/parameters/logoColor' },
{ $ref: '#/components/parameters/label' },
{ $ref: '#/components/parameters/labelColor' },
{ $ref: '#/components/parameters/color' },
{ $ref: '#/components/parameters/cacheSeconds' },
{ $ref: '#/components/parameters/link' },
]
function getCodeSamples(altText) {
return [
{
lang: 'URL',
label: 'URL',
source: '$url',
},
{
lang: 'Markdown',
label: 'Markdown',
source: `![${altText}]($url)`,
},
{
lang: 'reStructuredText',
label: 'rSt',
source: `.. image:: $url\n: alt: ${altText}`,
},
{
lang: 'AsciiDoc',
label: 'AsciiDoc',
source: `image:$url[${altText}]`,
},
{
lang: 'HTML',
label: 'HTML',
source: `<img alt="${altText}" src="$url">`,
},
]
}
function pattern2openapi(pattern) {
return pattern
.replace(/:([A-Za-z0-9_\-.]+)(?=[/]?)/g, (matches, grp1) => `{${grp1}}`)
.replace(/\([^)]*\)/g, '')
.replace(/\+$/, '')
}
function getEnum(pattern, paramName) {
const re = new RegExp(`${paramName}\\(([A-Za-z0-9_\\-|]+)\\)`)
const match = pattern.match(re)
if (match === null) {
return undefined
}
if (!match[1].includes('|')) {
return undefined
}
return match[1].split('|')
}
function param2openapi(pattern, paramName, exampleValue, paramType) {
const outParam = {}
outParam.name = paramName
// We don't have description if we are building the OpenAPI spec from examples[]
outParam.in = paramType
if (paramType === 'path') {
outParam.required = true
} else {
/* Occasionally we do have required query params, but we can't
detect this if we are building the OpenAPI spec from examples[]
so just assume all query params are optional */
outParam.required = false
}
if (exampleValue === null && paramType === 'query') {
outParam.schema = { type: 'boolean' }
outParam.allowEmptyValue = true
} else {
outParam.schema = { type: 'string' }
}
if (paramType === 'path') {
outParam.schema.enum = getEnum(pattern, paramName)
}
outParam.example = exampleValue
return outParam
}
function getVariants(pattern) {
/*
given a URL pattern (which may include '/one/or/:more?/:optional/:parameters*')
return an array of all possible permutations:
[
'/one/or/:more/:optional/:parameters',
'/one/or/:optional/:parameters',
'/one/or/:more/:optional',
'/one/or/:optional',
]
*/
const patterns = [pattern.split('/')]
while (patterns.flat().find(p => p.endsWith('?') || p.endsWith('*'))) {
for (let i = 0; i < patterns.length; i++) {
const pattern = patterns[i]
for (let j = 0; j < pattern.length; j++) {
const path = pattern[j]
if (path.endsWith('?') || path.endsWith('*')) {
pattern[j] = path.slice(0, -1)
patterns.push(patterns[i].filter(p => p !== pattern[j]))
}
}
}
}
for (let i = 0; i < patterns.length; i++) {
patterns[i] = patterns[i].join('/')
}
return patterns
}
function examples2openapi(examples) {
const paths = {}
for (const example of examples) {
const patterns = getVariants(example.example.pattern)
for (const pattern of patterns) {
const openApiPattern = pattern2openapi(pattern)
if (
openApiPattern.includes('*') ||
openApiPattern.includes('?') ||
openApiPattern.includes('+') ||
openApiPattern.includes('(')
) {
throw new Error(`unexpected characters in pattern '${openApiPattern}'`)
}
/*
There's several things going on in this block:
1. Filter out any examples for params that don't appear
in this variant of the route
2. Make sure we add params to the array
in the same order they appear in the route
3. If there are any params we don't have an example value for,
make sure they still appear in the pathParams array with
exampleValue == undefined anyway
*/
const pathParams = []
for (const param of openApiPattern
.split('/')
.filter(p => p.startsWith('{') && p.endsWith('}'))) {
const paramName = param.slice(1, -1)
const exampleValue = example.example.namedParams[paramName]
pathParams.push(param2openapi(pattern, paramName, exampleValue, 'path'))
}
const queryParams = example.example.queryParams || {}
const parameters = [
...pathParams,
...Object.entries(queryParams).map(([paramName, exampleValue]) =>
param2openapi(pattern, paramName, exampleValue, 'query')
),
...globalParamRefs,
]
paths[openApiPattern] = {
get: {
summary: example.title,
description: example?.documentation?.__html
.replace(/<br>/g, '<br />') // react does not like <br>
.replace(/{/g, '&#123;')
.replace(/}/g, '&#125;')
.replace(/<style>(.|\n)*?<\/style>/, ''), // workaround for w3c-validation TODO: remove later
parameters,
'x-code-samples': getCodeSamples(example.title),
},
}
}
}
return paths
}
function addGlobalProperties(endpoints) {
const paths = {}
for (const key of Object.keys(endpoints)) {
paths[key] = endpoints[key]
paths[key].get.parameters = [
...paths[key].get.parameters,
...globalParamRefs,
]
paths[key].get['x-code-samples'] = getCodeSamples(paths[key].get.summary)
}
return paths
}
function services2openapi(services) {
const paths = {}
for (const service of services) {
if (service.openApi) {
// if the service declares its own OpenAPI definition, use that...
for (const [key, value] of Object.entries(
addGlobalProperties(service.openApi)
)) {
if (key in paths) {
throw new Error(`Conflicting route: ${key}`)
}
paths[key] = value
}
} else {
// ...otherwise do our best to build one from examples[]
for (const [key, value] of Object.entries(
examples2openapi(service.examples)
)) {
// allow conflicting routes for legacy examples
paths[key] = value
}
}
}
return paths
}
function category2openapi(category, services) {
const spec = {
openapi: '3.0.0',
info: {
version: '1.0.0',
title: category.name,
license: {
name: 'CC0',
},
},
servers: [{ url: baseUrl }],
components: {
parameters: {
style: {
name: 'style',
in: 'query',
required: false,
description:
'One of: flat (default), flat-square, plastic, for-the-badge, social',
schema: {
type: 'string',
},
example: 'flat',
},
logo: {
name: 'logo',
in: 'query',
required: false,
description:
'One of the named logos (bitcoin, dependabot, gitlab, npm, paypal, serverfault, stackexchange, superuser, telegram, travis) or simple-icons. All simple-icons are referenced using icon slugs. You can click the icon title on <a href="https://simpleicons.org/" rel="noopener noreferrer" target="_blank">simple-icons</a> to copy the slug or they can be found in the <a href="https://github.com/simple-icons/simple-icons/blob/master/slugs.md">slugs.md file</a> in the simple-icons repository.',
schema: {
type: 'string',
},
example: 'appveyor',
},
logoColor: {
name: 'logoColor',
in: 'query',
required: false,
description:
'The color of the logo (hex, rgb, rgba, hsl, hsla and css named colors supported). Supported for named logos and Shields logos but not for custom logos. For multicolor Shields logos, the corresponding named logo will be used and colored.',
schema: {
type: 'string',
},
example: 'violet',
},
label: {
name: 'label',
in: 'query',
required: false,
description:
'Override the default left-hand-side text (<a href="https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding">URL-Encoding</a> needed for spaces or special characters!)',
schema: {
type: 'string',
},
example: 'healthiness',
},
labelColor: {
name: 'labelColor',
in: 'query',
required: false,
description:
'Background color of the left part (hex, rgb, rgba, hsl, hsla and css named colors supported).',
schema: {
type: 'string',
},
example: 'abcdef',
},
color: {
name: 'color',
in: 'query',
required: false,
description:
'Background color of the right part (hex, rgb, rgba, hsl, hsla and css named colors supported).',
schema: {
type: 'string',
},
example: 'fedcba',
},
cacheSeconds: {
name: 'cacheSeconds',
in: 'query',
required: false,
description:
'HTTP cache lifetime (rules are applied to infer a default value on a per-badge basis, any values specified below the default will be ignored).',
schema: {
type: 'string',
},
example: '3600',
},
link: {
name: 'link',
in: 'query',
required: false,
description:
'Specify what clicking on the left/right of a badge should do. Note that this only works when integrating your badge in an `<object>` HTML tag, but not an `<img>` tag or a markup language.',
style: 'form',
explode: true,
schema: {
type: 'array',
maxItems: 2,
items: {
type: 'string',
},
},
},
},
},
paths: services2openapi(services),
}
return spec
}
export { category2openapi }

View File

@@ -0,0 +1,379 @@
import chai from 'chai'
import { category2openapi } from './openapi.js'
import BaseJsonService from './base-json.js'
const { expect } = chai
class OpenApiService extends BaseJsonService {
static category = 'build'
static route = { base: 'openapi/service', pattern: ':packageName/:distTag*' }
// this service defines its own API Paths Object
static openApi = {
'/openapi/service/{packageName}': {
get: {
summary: 'OpenApiService Summary',
description: 'OpenApiService Description',
parameters: [
{
name: 'packageName',
description: 'packageName description',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'badge-maker',
},
],
},
},
'/openapi/service/{packageName}/{distTag}': {
get: {
summary: 'OpenApiService Summary (with Tag)',
description: 'OpenApiService Description (with Tag)',
parameters: [
{
name: 'packageName',
description: 'packageName description',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'badge-maker',
},
{
name: 'distTag',
description: 'distTag description',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'latest',
},
],
},
},
}
}
class LegacyService extends BaseJsonService {
static category = 'build'
static route = { base: 'legacy/service', pattern: ':packageName/:distTag*' }
// this service defines an Examples Array
static examples = [
{
title: 'LegacyService Title',
namedParams: { packageName: 'badge-maker' },
staticPreview: { label: 'build', message: 'passing' },
documentation: 'LegacyService Description',
},
{
title: 'LegacyService Title (with Tag)',
namedParams: { packageName: 'badge-maker', distTag: 'latest' },
staticPreview: { label: 'build', message: 'passing' },
documentation: 'LegacyService Description (with Tag)',
},
]
}
const expected = {
openapi: '3.0.0',
info: { version: '1.0.0', title: 'build', license: { name: 'CC0' } },
servers: [{ url: 'https://img.shields.io' }],
components: {
parameters: {
style: {
name: 'style',
in: 'query',
required: false,
description:
'One of: flat (default), flat-square, plastic, for-the-badge, social',
schema: { type: 'string' },
example: 'flat',
},
logo: {
name: 'logo',
in: 'query',
required: false,
description:
'One of the named logos (bitcoin, dependabot, gitlab, npm, paypal, serverfault, stackexchange, superuser, telegram, travis) or simple-icons. All simple-icons are referenced using icon slugs. You can click the icon title on <a href="https://simpleicons.org/" rel="noopener noreferrer" target="_blank">simple-icons</a> to copy the slug or they can be found in the <a href="https://github.com/simple-icons/simple-icons/blob/master/slugs.md">slugs.md file</a> in the simple-icons repository.',
schema: { type: 'string' },
example: 'appveyor',
},
logoColor: {
name: 'logoColor',
in: 'query',
required: false,
description:
'The color of the logo (hex, rgb, rgba, hsl, hsla and css named colors supported). Supported for named logos and Shields logos but not for custom logos. For multicolor Shields logos, the corresponding named logo will be used and colored.',
schema: { type: 'string' },
example: 'violet',
},
label: {
name: 'label',
in: 'query',
required: false,
description:
'Override the default left-hand-side text (<a href="https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding">URL-Encoding</a> needed for spaces or special characters!)',
schema: { type: 'string' },
example: 'healthiness',
},
labelColor: {
name: 'labelColor',
in: 'query',
required: false,
description:
'Background color of the left part (hex, rgb, rgba, hsl, hsla and css named colors supported).',
schema: { type: 'string' },
example: 'abcdef',
},
color: {
name: 'color',
in: 'query',
required: false,
description:
'Background color of the right part (hex, rgb, rgba, hsl, hsla and css named colors supported).',
schema: { type: 'string' },
example: 'fedcba',
},
cacheSeconds: {
name: 'cacheSeconds',
in: 'query',
required: false,
description:
'HTTP cache lifetime (rules are applied to infer a default value on a per-badge basis, any values specified below the default will be ignored).',
schema: { type: 'string' },
example: '3600',
},
link: {
name: 'link',
in: 'query',
required: false,
description:
'Specify what clicking on the left/right of a badge should do. Note that this only works when integrating your badge in an `<object>` HTML tag, but not an `<img>` tag or a markup language.',
style: 'form',
explode: true,
schema: { type: 'array', maxItems: 2, items: { type: 'string' } },
},
},
},
paths: {
'/openapi/service/{packageName}': {
get: {
summary: 'OpenApiService Summary',
description: 'OpenApiService Description',
parameters: [
{
name: 'packageName',
description: 'packageName description',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'badge-maker',
},
{ $ref: '#/components/parameters/style' },
{ $ref: '#/components/parameters/logo' },
{ $ref: '#/components/parameters/logoColor' },
{ $ref: '#/components/parameters/label' },
{ $ref: '#/components/parameters/labelColor' },
{ $ref: '#/components/parameters/color' },
{ $ref: '#/components/parameters/cacheSeconds' },
{ $ref: '#/components/parameters/link' },
],
'x-code-samples': [
{ lang: 'URL', label: 'URL', source: '$url' },
{
lang: 'Markdown',
label: 'Markdown',
source: '![OpenApiService Summary]($url)',
},
{
lang: 'reStructuredText',
label: 'rSt',
source: '.. image:: $url\n: alt: OpenApiService Summary',
},
{
lang: 'AsciiDoc',
label: 'AsciiDoc',
source: 'image:$url[OpenApiService Summary]',
},
{
lang: 'HTML',
label: 'HTML',
source: '<img alt="OpenApiService Summary" src="$url">',
},
],
},
},
'/openapi/service/{packageName}/{distTag}': {
get: {
summary: 'OpenApiService Summary (with Tag)',
description: 'OpenApiService Description (with Tag)',
parameters: [
{
name: 'packageName',
description: 'packageName description',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'badge-maker',
},
{
name: 'distTag',
description: 'distTag description',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'latest',
},
{ $ref: '#/components/parameters/style' },
{ $ref: '#/components/parameters/logo' },
{ $ref: '#/components/parameters/logoColor' },
{ $ref: '#/components/parameters/label' },
{ $ref: '#/components/parameters/labelColor' },
{ $ref: '#/components/parameters/color' },
{ $ref: '#/components/parameters/cacheSeconds' },
{ $ref: '#/components/parameters/link' },
],
'x-code-samples': [
{ lang: 'URL', label: 'URL', source: '$url' },
{
lang: 'Markdown',
label: 'Markdown',
source: '![OpenApiService Summary (with Tag)]($url)',
},
{
lang: 'reStructuredText',
label: 'rSt',
source:
'.. image:: $url\n: alt: OpenApiService Summary (with Tag)',
},
{
lang: 'AsciiDoc',
label: 'AsciiDoc',
source: 'image:$url[OpenApiService Summary (with Tag)]',
},
{
lang: 'HTML',
label: 'HTML',
source: '<img alt="OpenApiService Summary (with Tag)" src="$url">',
},
],
},
},
'/legacy/service/{packageName}/{distTag}': {
get: {
summary: 'LegacyService Title (with Tag)',
description: 'LegacyService Description (with Tag)',
parameters: [
{
name: 'packageName',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'badge-maker',
},
{
name: 'distTag',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'latest',
},
{ $ref: '#/components/parameters/style' },
{ $ref: '#/components/parameters/logo' },
{ $ref: '#/components/parameters/logoColor' },
{ $ref: '#/components/parameters/label' },
{ $ref: '#/components/parameters/labelColor' },
{ $ref: '#/components/parameters/color' },
{ $ref: '#/components/parameters/cacheSeconds' },
{ $ref: '#/components/parameters/link' },
],
'x-code-samples': [
{ lang: 'URL', label: 'URL', source: '$url' },
{
lang: 'Markdown',
label: 'Markdown',
source: '![LegacyService Title (with Tag)]($url)',
},
{
lang: 'reStructuredText',
label: 'rSt',
source: '.. image:: $url\n: alt: LegacyService Title (with Tag)',
},
{
lang: 'AsciiDoc',
label: 'AsciiDoc',
source: 'image:$url[LegacyService Title (with Tag)]',
},
{
lang: 'HTML',
label: 'HTML',
source: '<img alt="LegacyService Title (with Tag)" src="$url">',
},
],
},
},
'/legacy/service/{packageName}': {
get: {
summary: 'LegacyService Title (with Tag)',
description: 'LegacyService Description (with Tag)',
parameters: [
{
name: 'packageName',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'badge-maker',
},
{ $ref: '#/components/parameters/style' },
{ $ref: '#/components/parameters/logo' },
{ $ref: '#/components/parameters/logoColor' },
{ $ref: '#/components/parameters/label' },
{ $ref: '#/components/parameters/labelColor' },
{ $ref: '#/components/parameters/color' },
{ $ref: '#/components/parameters/cacheSeconds' },
{ $ref: '#/components/parameters/link' },
],
'x-code-samples': [
{ lang: 'URL', label: 'URL', source: '$url' },
{
lang: 'Markdown',
label: 'Markdown',
source: '![LegacyService Title (with Tag)]($url)',
},
{
lang: 'reStructuredText',
label: 'rSt',
source: '.. image:: $url\n: alt: LegacyService Title (with Tag)',
},
{
lang: 'AsciiDoc',
label: 'AsciiDoc',
source: 'image:$url[LegacyService Title (with Tag)]',
},
{
lang: 'HTML',
label: 'HTML',
source: '<img alt="LegacyService Title (with Tag)" src="$url">',
},
],
},
},
},
}
function clean(obj) {
// remove any undefined values in the object
return JSON.parse(JSON.stringify(obj))
}
describe('category2openapi', function () {
it('generates an Open API spec', function () {
expect(
clean(
category2openapi({ name: 'build' }, [
OpenApiService.getDefinition(),
LegacyService.getDefinition(),
])
)
).to.deep.equal(expected)
})
})

View File

@@ -46,6 +46,28 @@ const serviceDefinition = Joi.object({
})
)
.default([]),
openApi: Joi.object().pattern(
/./,
Joi.object({
get: Joi.object({
summary: Joi.string().required(),
description: Joi.string().required(),
parameters: Joi.array()
.items(
Joi.object({
name: Joi.string().required(),
description: Joi.string(),
in: Joi.string().valid('query', 'path').required(),
required: Joi.boolean().required(),
schema: Joi.object({ type: Joi.string().required() }).required(),
example: Joi.string(),
})
)
.min(1)
.required(),
}).required(),
}).required()
),
}).required()
function assertValidServiceDefinition(example, message = undefined) {

View File

@@ -20,7 +20,9 @@ export default class SqlTokenPersistence {
}
async stop() {
await this.pool.end()
if (this.pool) {
await this.pool.end()
}
}
async onTokenAdded(token) {

View File

@@ -45,14 +45,14 @@ The tests are also divided into several parts:
7. [The service tests themselves][service tests] live integration tests of the
services, and some mocked tests
1. `*.tester.js` in subfolders of [`services`][services]
8. Integration tests of Redis-backed persistence code
1. [`core/token-pooling/redis-token-persistence.integration.js`][redis-token-persistence.integration]
8. Integration tests of PostgreSQL-backed persistence code
1. [`core/token-pooling/sql-token-persistence.integration.js`][sql-token-persistence.integration]
9. Integration tests of the GitHub authorization code
1. [`services/github/github-api-provider.integration.js`][github-api-provider.integration]
[service-test-runner]: https://github.com/badges/shields/tree/master/core/service-test-runner
[service tests]: https://github.com/badges/shields/blob/master/doc/service-tests.md
[redis-token-persistence.integration]: https://github.com/badges/shields/blob/master/core/token-pooling/redis-token-persistence.integration.js
[sql-token-persistence.integration]: https://github.com/badges/shields/blob/master/core/token-pooling/sql-token-persistence.integration.js
[github-api-provider.integration]: https://github.com/badges/shields/blob/master/services/github/github-api-provider.integration.js
Our goal is to reach 100% coverage of the code in the

View File

@@ -14,49 +14,41 @@ Production hosting is managed by the Shields ops team:
[operations issues]: https://github.com/badges/shields/issues?q=is%3Aissue+is%3Aopen+label%3Aoperations
[ops discord]: https://discordapp.com/channels/308323056592486420/480747695879749633
| Component | Subcomponent | People with access |
| ----------------------------- | ------------------------------- | --------------------------------------------------------------- |
| shields-io-production | Full access | @calebcartwright, @chris48s, @paulmelnikow |
| shields-io-production | Access management | @calebcartwright, @chris48s, @paulmelnikow |
| Compose.io Redis | Account owner | @paulmelnikow |
| Compose.io Redis | Account access | @paulmelnikow |
| Compose.io Redis | Database connection credentials | @calebcartwright, @chris48s, @paulmelnikow, @pyvesb |
| Raster server | Full access as team members | @paulmelnikow, @chris48s, @calebcartwright, @platan |
| shields-server.com redirector | Full access as team members | @paulmelnikow, @chris48s, @calebcartwright, @platan |
| Cloudflare (CDN) | Account owner | @espadrine |
| Cloudflare (CDN) | Access management | @espadrine |
| Cloudflare (CDN) | Admin access | @calebcartwright, @chris48s, @espadrine, @paulmelnikow, @PyvesB |
| Twitch | OAuth app | @PyvesB |
| Discord | OAuth app | @PyvesB |
| YouTube | Account owner | @PyvesB |
| GitLab | Account owner | @calebcartwright |
| GitLab | Account access | @calebcartwright, @chris48s, @paulmelnikow, @PyvesB |
| OpenStreetMap (for Wheelmap) | Account owner | @paulmelnikow |
| DNS | Account owner | @olivierlacan |
| DNS | Read-only account access | @espadrine, @paulmelnikow, @chris48s |
| Sentry | Error reports | @espadrine, @paulmelnikow |
| Metrics server | Owner | @platan |
| UptimeRobot | Account owner | @paulmelnikow |
| More metrics | Owner | @RedSparr0w |
| Component | Subcomponent | People with access |
| ----------------------------- | --------------------------- | --------------------------------------------------------------- |
| shields-io-production | Full access | @calebcartwright, @chris48s, @paulmelnikow |
| shields-io-production | Access management | @calebcartwright, @chris48s, @paulmelnikow |
| Raster server | Full access as team members | @paulmelnikow, @chris48s, @calebcartwright, @platan |
| shields-server.com redirector | Full access as team members | @paulmelnikow, @chris48s, @calebcartwright, @platan |
| Cloudflare (CDN) | Account owner | @espadrine |
| Cloudflare (CDN) | Access management | @espadrine |
| Cloudflare (CDN) | Admin access | @calebcartwright, @chris48s, @espadrine, @paulmelnikow, @PyvesB |
| Twitch | OAuth app | @PyvesB |
| Discord | OAuth app | @PyvesB |
| YouTube | Account owner | @PyvesB |
| GitLab | Account owner | @calebcartwright |
| GitLab | Account access | @calebcartwright, @chris48s, @paulmelnikow, @PyvesB |
| OpenStreetMap (for Wheelmap) | Account owner | @paulmelnikow |
| DNS | Account owner | @olivierlacan |
| DNS | Read-only account access | @espadrine, @paulmelnikow, @chris48s |
| Sentry | Error reports | @espadrine, @paulmelnikow |
| Metrics server | Owner | @platan |
| UptimeRobot | Account owner | @paulmelnikow |
| More metrics | Owner | @RedSparr0w |
## Attached state
Shields has mercifully little persistent state:
1. The GitHub tokens we collect are saved on each server in a cloud Redis
database. They can also be fetched from the [GitHub auth admin endpoint][]
for debugging.
1. The GitHub tokens we collect are stored in a fly.io postgres database
2. The server keeps the [resource cache][] in memory. It is neither
persisted nor inspectable.
[github auth admin endpoint]: https://github.com/badges/shields/blob/master/services/github/auth/admin.js
[resource cache]: https://github.com/badges/shields/blob/master/core/base-service/resource-cache.js
## Configuration
To bootstrap the configuration process,
[the script that starts the server][start-shields.sh] sets a single
environment variable:
To bootstrap the configuration of non-secret settings, we set a single environment variable:
```
NODE_CONFIG_ENV=shields-io-production
@@ -71,7 +63,8 @@ files:
contains non-secrets which are checked in to the main repo.
- [`default.yml`][default.yml]. This file contains defaults.
[start-shields.sh]: https://github.com/badges/ServerScript/blob/master/start-shields.sh#L7
Secrets are supplied directly as environment vars.
[config]: https://github.com/lorenwest/node-config/wiki/Configuration-Files
[local-shields-io-production.yml]: ../config/local-shields-io-production.template.yml
[shields-io-production.yml]: ../config/shields-io-production.yml

View File

@@ -45,11 +45,11 @@ We are happy to document and collate any self-hosting patterns/approaches that o
We try to make it as easy as possible for users to self-host a Shields server so we publish a few releases of the server. Please be sure to refer to the [self hosting guide][self hosting] for a detailed walk through on how to spin up a server.
- The server uses [Calendar Versioning](https://calver.org/). Tags of the form `server-YYYY-MM-DD` are server releases (these are the tags that are relevant to self-hosting users, e.g. [server-2021-02-01](https://github.com/badges/shields/releases/tag/server-2021-02-01)).
- As well as [tags on GitHub](https://github.com/badges/shields/tags), server releases are also pushed to [DockerHub](https://registry.hub.docker.com/r/shieldsio/shields/tags). See the self-hosting section on [Docker](https://github.com/badges/shields/blob/master/doc/self-hosting.md#Docker) for more details.
- As well as [tags on GitHub](https://github.com/badges/shields/tags), server releases are also pushed to [DockerHub](https://registry.hub.docker.com/r/shieldsio/shields/tags) and [GitHub Container Registry](https://github.com/badges/shields/pkgs/container/shields/versions?filters%5Bversion_type%5D=tagged). See the self-hosting section on [Docker](https://github.com/badges/shields/blob/master/doc/self-hosting.md#Docker) for more details.
- We publish release notes for server releases in the [CHANGELOG](https://github.com/badges/shields/blob/master/CHANGELOG.md). There may occasionally be non-backwards compatible changes to be aware of.
- We will normally put out one release per month. If there is a security patch or major bugfix affecting self-hosting users, we may put out an out-of-sequence release.
- Releases are just a snapshot in time. We advise always tracking the latest release to ensure you are up-to-date with the latest bug fixes and security updates. There are no 'patch' releases - we don't backport fixes to old releases. Tagged versions just provide a convenient way to apply upgrades in a controlled way or roll back to an older version if necessary and communicate about versions.
- You can stay on the bleeding edge by tracking the `master` branch for source installs or the `next` tag on DockerHub.
- You can stay on the bleeding edge by tracking the `master` branch for source installs or the `next` tag on DockerHub/GHCR.
[shields.io]: https://shields.io
[npm package]: https://www.npmjs.com/package/badge-maker

View File

@@ -71,18 +71,30 @@ vercel
## Docker
### DockerHub
### Public Images
We publish images to DockerHub at https://registry.hub.docker.com/r/shieldsio/shields
We publish images to:
The `next` tag is the latest build from `master`, or tagged releases are available
https://registry.hub.docker.com/r/shieldsio/shields/tags
- DockerHub at https://registry.hub.docker.com/r/shieldsio/shields and
- GitHub Container Registry at https://github.com/badges/shields/pkgs/container/shields
```console
The `next` tag is the latest build from `master`, or tagged snapshot releases are available:
- https://registry.hub.docker.com/r/shieldsio/shields/tags
- https://github.com/badges/shields/pkgs/container/shields/versions?filters%5Bversion_type%5D=tagged
```sh
# DockerHub
$ docker pull shieldsio/shields:next
$ docker run shieldsio/shields:next
```
```sh
# GHCR
$ docker pull ghcr.io/badges/shields:next
$ docker pull ghcr.io/badges/shields:next
```
### Building Docker Image Locally
Alternatively, you can build and run the server locally using Docker. First build an image:

View File

View File

@@ -327,17 +327,18 @@ export default function Usage({ baseUrl }: { baseUrl: string }): JSX.Element {
<QueryParam
documentation={
<span>
Insert one of the named logos from (<NamedLogos />) or{' '}
Insert one of the named logos from (<NamedLogos />) or
simple-icons. All simple-icons are referenced using icon slugs.
You can click the icon title on{' '}
<a
href="https://simpleicons.org/"
rel="noopener noreferrer"
target="_blank"
>
simple-icons
</a>
. Simple-icons are referenced using icon slugs which can be
found on the simple-icons site or in the{' '}
<a href="https://github.com/simple-icons/simple-icons/blob/develop/slugs.md">
</a>{' '}
to copy the slug or they can be found in the{' '}
<a href="https://github.com/simple-icons/simple-icons/blob/master/slugs.md">
slugs.md file
</a>{' '}
in the simple-icons repository.

3305
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -24,8 +24,8 @@
"@fontsource/lato": "^4.5.10",
"@fontsource/lekton": "^4.5.11",
"@renovate/pep440": "^1.0.0",
"@renovatebot/ruby-semver": "^2.1.8",
"@sentry/node": "^7.38.0",
"@renovatebot/ruby-semver": "^2.1.10",
"@sentry/node": "^7.47.0",
"@shields_io/camp": "^18.1.2",
"badge-maker": "file:badge-maker",
"bytes": "^3.1.2",
@@ -39,14 +39,14 @@
"decamelize": "^3.2.0",
"emojic": "^1.1.17",
"escape-string-regexp": "^4.0.0",
"fast-xml-parser": "^4.1.2",
"glob": "^8.1.0",
"fast-xml-parser": "^4.1.3",
"glob": "^9.3.4",
"global-agent": "^3.0.0",
"got": "^12.5.3",
"got": "^12.6.0",
"graphql": "^15.6.1",
"graphql-tag": "^2.12.6",
"ioredis": "5.3.1",
"joi": "17.8.3",
"joi": "17.9.1",
"joi-extension-semver": "5.0.0",
"js-yaml": "^4.1.0",
"jsonpath": "~1.1.1",
@@ -57,14 +57,14 @@
"node-pg-migrate": "^6.2.2",
"parse-link-header": "^2.0.0",
"path-to-regexp": "^6.2.1",
"pg": "^8.9.0",
"pg": "^8.10.0",
"pretty-bytes": "^6.1.0",
"priorityqueuejs": "^2.0.0",
"prom-client": "^14.1.1",
"qs": "^6.11.0",
"prom-client": "^14.2.0",
"qs": "^6.11.1",
"query-string": "^8.1.0",
"semver": "~7.3.8",
"simple-icons": "8.5.0",
"simple-icons": "8.9.0",
"webextension-store-meta": "^1.0.5",
"xmldom": "~0.6.0",
"xpath": "~0.0.32"
@@ -145,7 +145,7 @@
]
},
"devDependencies": {
"@babel/core": "^7.21.0",
"@babel/core": "^7.21.4",
"@babel/polyfill": "^7.12.1",
"@babel/register": "7.21.0",
"@istanbuljs/schema": "^0.1.3",
@@ -159,8 +159,8 @@
"@types/react-modal": "^3.13.1",
"@types/react-select": "^4.0.17",
"@types/styled-components": "5.1.26",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.46.0",
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.55.0",
"babel-plugin-inline-react-svg": "^2.0.2",
"babel-preset-gatsby": "^2.22.0",
"c8": "^7.13.0",
@@ -171,28 +171,28 @@
"chai-string": "^1.4.0",
"child-process-promise": "^2.2.1",
"clipboard-copy": "^4.0.1",
"concurrently": "^7.6.0",
"cypress": "^12.6.0",
"concurrently": "^8.0.1",
"cypress": "^12.9.0",
"cypress-wait-for-stable-dom": "^0.1.0",
"danger": "^11.2.3",
"deepmerge": "^4.3.0",
"danger": "^11.2.4",
"deepmerge": "^4.3.1",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.6.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-standard": "^16.0.3",
"eslint-config-standard-jsx": "^10.0.0",
"eslint-config-standard-react": "^11.0.1",
"eslint-plugin-chai-friendly": "^0.7.2",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-cypress": "^2.13.2",
"eslint-plugin-icedfrisby": "^0.1.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsdoc": "^40.0.0",
"eslint-plugin-jsdoc": "^40.1.1",
"eslint-plugin-mocha": "^10.1.0",
"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.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-sort-class-members": "^1.16.0",
"eslint-plugin-sort-class-members": "^1.17.0",
"fetch-ponyfill": "^7.1.0",
"form-data": "^4.0.0",
"gatsby": "4.23.1",
@@ -208,7 +208,7 @@
"is-svg": "^4.3.2",
"js-yaml-loader": "^1.2.2",
"jsdoc": "^4.0.2",
"lint-staged": "^13.1.2",
"lint-staged": "^13.2.1",
"lodash.debounce": "^4.0.8",
"lodash.difference": "^4.5.0",
"minimist": "^1.2.8",
@@ -217,12 +217,12 @@
"mocha-junit-reporter": "^2.2.0",
"mocha-yaml-loader": "^1.0.3",
"nock": "13.3.0",
"node-mocks-http": "^1.12.1",
"nodemon": "^2.0.20",
"node-mocks-http": "^1.12.2",
"nodemon": "^2.0.22",
"npm-run-all": "^4.1.5",
"open-cli": "^7.1.0",
"open-cli": "^7.2.0",
"portfinder": "^1.0.32",
"prettier": "2.8.4",
"prettier": "2.8.7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-error-overlay": "^6.0.11",
@@ -232,17 +232,17 @@
"react-select": "^4.3.1",
"read-all-stdin-sync": "^1.0.5",
"redis-server": "^1.2.2",
"rimraf": "^4.1.2",
"rimraf": "^4.4.1",
"sazerac": "^2.0.0",
"simple-git-hooks": "^2.8.1",
"sinon": "^15.0.1",
"sinon": "^15.0.3",
"sinon-chai": "^3.7.0",
"snap-shot-it": "^7.9.10",
"start-server-and-test": "1.15.4",
"styled-components": "^5.3.6",
"start-server-and-test": "2.0.0",
"styled-components": "^5.3.9",
"ts-mocha": "^10.0.0",
"tsd": "^0.25.0",
"typescript": "^4.9.5",
"tsd": "^0.28.1",
"typescript": "^5.0.3",
"url": "^0.11.0"
},
"engines": {

View File

@@ -0,0 +1,49 @@
import fs from 'fs'
import path from 'path'
import yaml from 'js-yaml'
import { collectDefinitions } from '../core/base-service/loader.js'
import { category2openapi } from '../core/base-service/openapi.js'
const specsPath = path.join('frontend', 'categories')
function writeSpec(filename, spec) {
// Omit undefined
// https://github.com/nodeca/js-yaml/issues/356#issuecomment-312430599
const cleaned = JSON.parse(JSON.stringify(spec))
fs.writeFileSync(
filename,
yaml.dump(cleaned, { flowLevel: 5, forceQuotes: true })
)
}
;(async () => {
const definitions = await collectDefinitions()
for (const category of definitions.categories) {
const services = definitions.services.filter(
service => service.category === category.id && !service.isDeprecated
)
writeSpec(
path.join(specsPath, `${category.id}.yaml`),
category2openapi(category, services)
)
}
let coreServices = []
coreServices = coreServices.concat(
definitions.services.filter(
service => service.category === 'static' && !service.isDeprecated
)
)
coreServices = coreServices.concat(
definitions.services.filter(
service => service.category === 'dynamic' && !service.isDeprecated
)
)
writeSpec(
path.join(specsPath, '1core.yaml'),
category2openapi({ name: 'Core' }, coreServices)
)
})()

View File

@@ -3,6 +3,19 @@ import { collectDefinitions } from '../core/base-service/loader.js'
;(async () => {
const definitions = await collectDefinitions()
// filter out static, dynamic and debug badge examples
const publicCategories = definitions.categories.map(c => c.id)
definitions.services = definitions.services.filter(s =>
publicCategories.includes(s.category)
)
// drop the openApi property for the "legacy" frontend
for (const service of definitions.services) {
if (service.openApi) {
service.openApi = undefined
}
}
// Omit undefined
// https://github.com/nodeca/js-yaml/issues/356#issuecomment-312430599
const cleaned = JSON.parse(JSON.stringify(definitions))

View File

@@ -20,17 +20,17 @@ if (data.stats.passes > 0) {
process.stdout.write(`${data.stats.passes} passed\n`)
}
if (data.stats.failures > 0) {
process.stdout.write(`${data.stats.failures} failed\n\n`)
process.stdout.write(`${data.stats.failures} failed\n`)
}
if (data.stats.pending > 0) {
process.stdout.write(`${data.stats.pending} pending\n\n`)
process.exit(2)
process.stdout.write(`${data.stats.pending} pending\n`)
}
process.stdout.write('\n')
if (data.stats.failures > 0) {
for (const test of data.tests) {
process.stdout.write('## Failures\n\n')
for (const test of data.failures) {
if (test.err && Object.keys(test.err).length > 0) {
process.stdout.write(`### ${test.title}\n\n`)
process.stdout.write(`${test.fullTitle}\n\n`)
process.stdout.write('```\n')
process.stdout.write(`${test.err.stack}\n`)
@@ -38,3 +38,10 @@ if (data.stats.failures > 0) {
}
}
}
if (data.stats.pending > 0) {
process.stdout.write('## Pending\n\n')
for (const test of data.pending) {
process.stdout.write(`${test.fullTitle}\n\n`)
}
}

View File

@@ -1,12 +1,13 @@
import Joi from 'joi'
import { renderLicenseBadge } from '../licenses.js'
import { renderVersionBadge } from '../version.js'
import { BaseJsonService } from '../index.js'
import { BaseJsonService, InvalidResponse } from '../index.js'
const schema = Joi.object({
license: Joi.array().items(Joi.string()).single(),
version: Joi.object({
number: Joi.string().required(),
number: Joi.string().allow('').required(),
date: Joi.string().allow('').required(),
}).required(),
}).required()
@@ -14,7 +15,7 @@ class BaseCtanService extends BaseJsonService {
static defaultBadgeData = { label: 'ctan' }
async fetch({ library }) {
const url = `http://www.ctan.org/json/pkg/${library}`
const url = `https://www.ctan.org/json/2.0/pkg/${library}`
return this._requestJson({
schema,
url,
@@ -67,7 +68,22 @@ class CtanVersion extends BaseCtanService {
async handle({ library }) {
const json = await this.fetch({ library })
return renderVersionBadge({ version: json.version.number })
const version = json.version.number
if (version !== '') {
return renderVersionBadge({ version })
} else {
const date = json.version.date
if (date !== '') {
return renderVersionBadge({
version: date,
versionFormatter: color => 'blue',
})
} else {
return new InvalidResponse({
underlyingError: new Error('Both number and date are empty'),
})
}
}
}
}

View File

@@ -1,5 +1,13 @@
import Joi from 'joi'
import { ServiceTester } from '../tester.js'
import { isVPlusDottedVersionAtLeastOne } from '../test-validators.js'
import { withRegex } from '../test-validators.js'
// same as isVPlusDottedVersionAtLeastOne, but also accepts an optional
// single lowercase alphabet letter suffix
// e.g.: v1.81a
const isVPlusDottedVersionAtLeastOneWithOptionalAlphabetLetter = withRegex(
/^v\d+(\.\d+)?(\.\d+)?[a-z]?$/
)
export const t = new ServiceTester({
id: 'ctan',
@@ -14,11 +22,12 @@ t.create('license').get('/l/novel.json').expectBadge({
t.create('license missing')
.get('/l/novel.json')
.intercept(nock =>
nock('http://www.ctan.org')
.get('/json/pkg/novel')
nock('https://www.ctan.org')
.get('/json/2.0/pkg/novel')
.reply(200, {
version: {
number: 'notRelevant',
date: 'notRelevant',
},
})
)
@@ -30,12 +39,13 @@ t.create('license missing')
t.create('single license')
.get('/l/tex.json')
.intercept(nock =>
nock('http://www.ctan.org')
.get('/json/pkg/tex')
nock('https://www.ctan.org')
.get('/json/2.0/pkg/tex')
.reply(200, {
license: 'knuth',
version: {
number: 'notRelevant',
date: 'notRelevant',
},
})
)
@@ -46,17 +56,18 @@ t.create('single license')
t.create('version').get('/v/novel.json').expectBadge({
label: 'ctan',
message: isVPlusDottedVersionAtLeastOne,
message: isVPlusDottedVersionAtLeastOneWithOptionalAlphabetLetter,
})
t.create('version')
.get('/v/novel.json')
.intercept(nock =>
nock('http://www.ctan.org')
.get('/json/pkg/novel')
nock('https://www.ctan.org')
.get('/json/2.0/pkg/novel')
.reply(200, {
version: {
number: 'v1.11',
date: '',
},
})
)
@@ -65,3 +76,9 @@ t.create('version')
message: 'v1.11',
color: 'blue',
})
t.create('date as version').get('/v/l3kernel.json').expectBadge({
label: 'ctan',
message: Joi.date().iso(),
color: 'blue',
})

View File

@@ -6,6 +6,53 @@ import jsonPath from './json-path.js'
export default class DynamicJson extends jsonPath(BaseJsonService) {
static enabledMetrics = [MetricNames.SERVICE_RESPONSE_SIZE]
static route = createRoute('json')
static openApi = {
'/badge/dynamic/json': {
get: {
summary: 'Dynamic JSON Badge',
description: `<p>
The Dynamic JSON Badge allows you to extract an arbitrary value from any
JSON Document using a JSONPath selector and show it on a badge.
</p>`,
parameters: [
{
name: 'url',
description: 'The URL to a JSON document',
in: 'query',
required: true,
schema: { type: 'string' },
example:
'https://github.com/badges/shields/raw/master/package.json',
},
{
name: 'query',
description:
'A <a href="https://jsonpath.com/">JSONPath</a> expression that will be used to query the document',
in: 'query',
required: true,
schema: { type: 'string' },
example: '$.name',
},
{
name: 'prefix',
description: 'Optional prefix to append to the value',
in: 'query',
required: false,
schema: { type: 'string' },
example: '[',
},
{
name: 'suffix',
description: 'Optional suffix to append to the value',
in: 'query',
required: false,
schema: { type: 'string' },
example: ']',
},
],
},
},
}
async fetch({ schema, url, errorMessages }) {
return this._requestJson({

View File

@@ -27,7 +27,7 @@ t.create('Malformed url')
)
.expectBadge({
label: 'Package Name',
message: 'inaccessible',
message: 'invalid',
color: 'lightgrey',
})

View File

@@ -15,6 +15,53 @@ export default class DynamicXml extends BaseService {
static category = 'dynamic'
static enabledMetrics = [MetricNames.SERVICE_RESPONSE_SIZE]
static route = createRoute('xml')
static openApi = {
'/badge/dynamic/xml': {
get: {
summary: 'Dynamic XML Badge',
description: `<p>
The Dynamic XML Badge allows you to extract an arbitrary value from any
XML Document using an XPath selector and show it on a badge.
</p>`,
parameters: [
{
name: 'url',
description: 'The URL to a XML document',
in: 'query',
required: true,
schema: { type: 'string' },
example: 'https://httpbin.org/xml',
},
{
name: 'query',
description:
'A <a href="http://xpather.com/">XPath</a> expression that will be used to query the document',
in: 'query',
required: true,
schema: { type: 'string' },
example: '//slideshow/slide[1]/title',
},
{
name: 'prefix',
description: 'Optional prefix to append to the value',
in: 'query',
required: false,
schema: { type: 'string' },
example: '[',
},
{
name: 'suffix',
description: 'Optional suffix to append to the value',
in: 'query',
required: false,
schema: { type: 'string' },
example: ']',
},
],
},
},
}
static defaultBadgeData = { label: 'custom badge' }
transform({ pathExpression, buffer }) {

View File

@@ -6,6 +6,53 @@ import jsonPath from './json-path.js'
export default class DynamicYaml extends jsonPath(BaseYamlService) {
static enabledMetrics = [MetricNames.SERVICE_RESPONSE_SIZE]
static route = createRoute('yaml')
static openApi = {
'/badge/dynamic/yaml': {
get: {
summary: 'Dynamic YAML Badge',
description: `<p>
The Dynamic YAML Badge allows you to extract an arbitrary value from any
YAML Document using a JSONPath selector and show it on a badge.
</p>`,
parameters: [
{
name: 'url',
description: 'The URL to a YAML document',
in: 'query',
required: true,
schema: { type: 'string' },
example:
'https://raw.githubusercontent.com/badges/shields/master/.github/dependabot.yml',
},
{
name: 'query',
description:
'A <a href="https://jsonpath.com/">JSONPath</a> expression that will be used to query the document',
in: 'query',
required: true,
schema: { type: 'string' },
example: '$.version',
},
{
name: 'prefix',
description: 'Optional prefix to append to the value',
in: 'query',
required: false,
schema: { type: 'string' },
example: '[',
},
{
name: 'suffix',
description: 'Optional suffix to append to the value',
in: 'query',
required: false,
schema: { type: 'string' },
example: ']',
},
],
},
},
}
async fetch({ schema, url, errorMessages }) {
return this._requestYaml({

View File

@@ -11,14 +11,144 @@ const queryParamSchema = Joi.object({
url: optionalUrl.required(),
}).required()
const description = `<p>
Using the endpoint badge, you can provide content for a badge through
a JSON endpoint. The content can be prerendered, or generated on the
fly. To strike a balance between responsiveness and bandwidth
utilization on one hand, and freshness on the other, cache behavior is
configurable, subject to the Shields minimum. The endpoint URL is
provided to Shields through the query string. Shields fetches it and
formats the badge.
</p>
<p>
The endpoint badge takes a single required query param: <code>url</code>, which is the URL to your JSON endpoint
</p>
<div>
<h2>Example JSON Endpoint Response</h2>
<code>&#123; "schemaVersion": 1, "label": "hello", "message": "sweet world", "color": "orange" &#125;</code>
<h2>Example Shields Response</h2>
<img src="https://img.shields.io/badge/hello-sweet_world-orange" />
</div>
<div>
<h2>Schema</h2>
<table>
<tbody>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
<tr>
<td><code>schemaVersion</code></td>
<td>Required. Always the number <code>1</code>.</td>
</tr>
<tr>
<td><code>label</code></td>
<td>
Required. The left text, or the empty string to omit the left side of
the badge. This can be overridden by the query string.
</td>
</tr>
<tr>
<td><code>message</code></td>
<td>Required. Can't be empty. The right text.</td>
</tr>
<tr>
<td><code>color</code></td>
<td>
Default: <code>lightgrey</code>. The right color. Supports the eight
named colors above, as well as hex, rgb, rgba, hsl, hsla and css named
colors. This can be overridden by the query string.
</td>
</tr>
<tr>
<td><code>labelColor</code></td>
<td>
Default: <code>grey</code>. The left color. This can be overridden by
the query string.
</td>
</tr>
<tr>
<td><code>isError</code></td>
<td>
Default: <code>false</code>. <code>true</code> to treat this as an
error badge. This prevents the user from overriding the color. In the
future, it may affect cache behavior.
</td>
</tr>
<tr>
<td><code>namedLogo</code></td>
<td>
Default: none. One of the named logos supported by Shields or
<a href="https://simpleicons.org/">simple-icons</a>. Can be overridden
by the query string.
</td>
</tr>
<tr>
<td><code>logoSvg</code></td>
<td>Default: none. An SVG string containing a custom logo.</td>
</tr>
<tr>
<td><code>logoColor</code></td>
<td>
Default: none. Same meaning as the query string. Can be overridden by
the query string. Only works for named logos and Shields logos. If you
override the color of a multicolor Shield logo, the corresponding
named logo will be used and colored.
</td>
</tr>
<tr>
<td><code>logoWidth</code></td>
<td>
Default: none. Same meaning as the query string. Can be overridden by
the query string.
</td>
</tr>
<tr>
<td><code>logoPosition</code></td>
<td>
Default: none. Same meaning as the query string. Can be overridden by
the query string.
</td>
</tr>
<tr>
<td><code>style</code></td>
<td>
Default: <code>flat</code>. The default template to use. Can be
overridden by the query string.
</td>
</tr>
</tbody>
</table>
</div>`
export default class Endpoint extends BaseJsonService {
static category = 'dynamic'
static route = {
base: 'endpoint',
pattern: '',
queryParamSchema,
}
static openApi = {
'/endpoint': {
get: {
summary: 'Endpoint Badge',
description,
parameters: [
{
name: 'url',
description: 'The URL to your JSON endpoint',
in: 'query',
required: true,
schema: { type: 'string' },
example: 'https://shields.redsparr0w.com/2473/monday',
},
],
},
},
}
static _cacheLength = 300
static defaultBadgeData = { label: 'custom badge' }

View File

@@ -1,6 +1,6 @@
import zlib from 'zlib'
import { expect } from 'chai'
import { getShieldsIcon } from '../../lib/logos.js'
import { getShieldsIcon, getSimpleIcon } from '../../lib/logos.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
@@ -73,13 +73,13 @@ t.create('named logo with color')
schemaVersion: 1,
label: 'hey',
message: 'yo',
namedLogo: 'npm',
namedLogo: 'github',
logoColor: 'blue',
})
)
.after((err, res, body) => {
expect(err).not.to.be.ok
expect(body).to.include(getShieldsIcon({ name: 'npm', color: 'blue' }))
expect(body).to.include(getSimpleIcon({ name: 'github', color: 'blue' }))
})
const logoSvg = Buffer.from(

View File

@@ -21,7 +21,7 @@ export default class GithubSize extends GithubAuthV3Service {
static route = {
base: 'github/size',
pattern: ':user/:repo/:path*',
pattern: ':user/:repo/:path+',
queryParamSchema,
}

View File

@@ -30,4 +30,13 @@ export default [
dateAdded: new Date('2019-11-29'),
...commonProps,
}),
redirector({
route: {
base: 'jenkins/coverage/api',
pattern: '',
},
category: 'coverage',
transformPath: () => '/jenkins/coverage/apiv1',
dateAdded: new Date('2023-03-21'),
}),
]

View File

@@ -53,3 +53,11 @@ t.create('api prefix + job url in path')
'https://jenkins.library.illinois.edu/job/OpenSourceProjects/job/Speedwagon/job/master'
)}`
)
t.create('old v1 api prefix to new prefix')
.get(
'/coverage/api.svg?jobUrl=http://loneraver.duckdns.org:8082/job/github/job/VisVid/job/master'
)
.expectRedirect(
'/jenkins/coverage/apiv1.svg?jobUrl=http://loneraver.duckdns.org:8082/job/github/job/VisVid/job/master'
)

View File

@@ -42,7 +42,7 @@ const formatMap = {
},
pluginSpecificPath: 'cobertura',
},
api: {
apiv1: {
schema: Joi.object({
results: Joi.object({
elements: Joi.array()
@@ -66,6 +66,25 @@ const formatMap = {
},
pluginSpecificPath: 'coverage/result',
},
apiv4: {
schema: Joi.object({
projectStatistics: Joi.object({
line: Joi.string()
.pattern(/\d+\.\d+%/)
.required(),
}).required(),
}).required(),
treeQueryParam: 'projectStatistics[line]',
transform: json => {
const lineCoverageStr = json.projectStatistics.line
const lineCoverage = lineCoverageStr.substring(
0,
lineCoverageStr.length - 1
)
return { coverage: Number.parseFloat(lineCoverage) }
},
pluginSpecificPath: 'coverage',
},
}
const documentation = `
@@ -74,7 +93,7 @@ const documentation = `
<ul>
<li><a href="https://plugins.jenkins.io/jacoco">JaCoCo</a></li>
<li><a href="https://plugins.jenkins.io/cobertura">Cobertura</a></li>
<li>Any plugin which integrates with the <a href="https://plugins.jenkins.io/code-coverage-api">Code Coverage API</a> (e.g. llvm-cov, Cobertura 1.13+, etc.)</li>
<li>Any plugin which integrates with version 1 or 4+ of the <a href="https://plugins.jenkins.io/code-coverage-api">Code Coverage API</a> (e.g. llvm-cov, Cobertura 1.13+, etc.)</li>
</ul>
</p>
`
@@ -84,7 +103,7 @@ export default class JenkinsCoverage extends JenkinsBase {
static route = {
base: 'jenkins/coverage',
pattern: ':format(jacoco|cobertura|api)',
pattern: ':format(jacoco|cobertura|apiv1|apiv4)',
queryParamSchema,
}

View File

@@ -31,14 +31,49 @@ t.create('cobertura: job found')
)
.expectBadge({ label: 'coverage', message: isIntegerPercentage })
t.create('code coverage API: job not found')
t.create('code coverage API v1: job not found')
.get(
'/api.json?jobUrl=https://jenkins.library.illinois.edu/job/does-not-exist'
'/apiv1.json?jobUrl=https://jenkins.library.illinois.edu/job/does-not-exist'
)
.expectBadge({ label: 'coverage', message: 'job or coverage not found' })
t.create('code coverage API: job found')
const coverageApiV1Response = {
_class: 'io.jenkins.plugins.coverage.targets.CoverageResult',
results: {
elements: [
{ name: 'Report', ratio: 100.0 },
{ name: 'Group', ratio: 100.0 },
{ name: 'Package', ratio: 66.666664 },
{ name: 'File', ratio: 52.0 },
{ name: 'Class', ratio: 52.0 },
{ name: 'Line', ratio: 40.66363 },
{ name: 'Conditional', ratio: 29.91968 },
],
},
}
t.create('code coverage API v1: job found')
.get(
'/api.json?jobUrl=http://loneraver.duckdns.org:8082/job/github/job/VisVid/job/master/'
'/apiv1.json?jobUrl=http://loneraver.duckdns.org:8082/job/github/job/VisVid/job/master'
)
.intercept(nock =>
nock(
'http://loneraver.duckdns.org:8082/job/github/job/VisVid/job/master/lastCompletedBuild'
)
.get('/coverage/result/api/json')
.query(true)
.reply(200, coverageApiV1Response)
)
.expectBadge({ label: 'coverage', message: isIntegerPercentage })
t.create('code coverage API v4+: job not found')
.get(
'/apiv4.json?jobUrl=https://jenkins.library.illinois.edu/job/does-not-exist'
)
.expectBadge({ label: 'coverage', message: 'job or coverage not found' })
t.create('code coverage API v4+: job found')
.get(
'/apiv4.json?jobUrl=https://jenkins.mm12.xyz/jenkins/job/nmfu/job/master'
)
.expectBadge({ label: 'coverage', message: isIntegerPercentage })

View File

@@ -52,9 +52,9 @@ export default class Netlify extends BaseSvgScrapingService {
const { buffer } = await this._request({
url,
})
if (buffer.includes('#0D544F')) return { message: 'passing' }
if (buffer.includes('#900B31')) return { message: 'failing' }
if (buffer.includes('#AB6F10')) return { message: 'building' }
if (buffer.includes('#0F4A21')) return { message: 'passing' }
if (buffer.includes('#800A20')) return { message: 'failing' }
if (buffer.includes('#603408')) return { message: 'building' }
return { message: 'unknown' }
}

View File

@@ -27,8 +27,8 @@ export default class NodeVersionBase extends NPMBase {
},
{
title: `${prefix} (scoped)`,
pattern: '@:scope/:packageName',
namedParams: { scope: 'stdlib', packageName: 'stdlib' },
pattern: ':scope/:packageName',
namedParams: { scope: '@stdlib', packageName: 'stdlib' },
staticPreview: this.renderStaticPreview({
nodeVersionRange: '>= 6.0.0',
}),
@@ -48,8 +48,8 @@ export default class NodeVersionBase extends NPMBase {
},
{
title: `${prefix} (scoped with tag)`,
pattern: '@:scope/:packageName/:tag',
namedParams: { scope: 'stdlib', packageName: 'stdlib', tag: 'latest' },
pattern: ':scope/:packageName/:tag',
namedParams: { scope: '@stdlib', packageName: 'stdlib', tag: 'latest' },
staticPreview: this.renderStaticPreview({
nodeVersionRange: '>= 6.0.0',
tag: 'latest',
@@ -59,8 +59,8 @@ export default class NodeVersionBase extends NPMBase {
},
{
title: `${prefix} (scoped with tag, custom registry)`,
pattern: '@:scope/:packageName/:tag',
namedParams: { scope: 'stdlib', packageName: 'stdlib', tag: 'latest' },
pattern: ':scope/:packageName/:tag',
namedParams: { scope: '@stdlib', packageName: 'stdlib', tag: 'latest' },
queryParams: { registry_uri: 'https://registry.npmjs.com' },
staticPreview: this.renderStaticPreview({
nodeVersionRange: '>= 6.0.0',

View File

@@ -23,32 +23,36 @@ export default class NpmsIOScore extends BaseJsonService {
static route = {
base: 'npms-io',
pattern:
':type(final|maintenance|popularity|quality)-score/:scope(@.+)?/:packageName',
':type(final-score|maintenance-score|popularity-score|quality-score)/:scope(@.+)?/:packageName',
}
static examples = [
{
title: 'npms.io (final)',
namedParams: { type: 'final', packageName: 'egg' },
namedParams: { type: 'final-score', packageName: 'egg' },
staticPreview: this.render({ score: 0.9711 }),
keywords,
},
{
title: 'npms.io (popularity)',
pattern: ':type/:scope/:packageName',
namedParams: { type: 'popularity', scope: '@vue', packageName: 'cli' },
namedParams: {
type: 'popularity-score',
scope: '@vue',
packageName: 'cli',
},
staticPreview: this.render({ type: 'popularity', score: 0.89 }),
keywords,
},
{
title: 'npms.io (quality)',
namedParams: { type: 'quality', packageName: 'egg' },
namedParams: { type: 'quality-score', packageName: 'egg' },
staticPreview: this.render({ type: 'quality', score: 0.98 }),
keywords,
},
{
title: 'npms.io (maintenance)',
namedParams: { type: 'maintenance', packageName: 'command' },
namedParams: { type: 'maintenance-score', packageName: 'command' },
staticPreview: this.render({ type: 'maintenance', score: 0.222 }),
keywords,
},
@@ -76,8 +80,10 @@ export default class NpmsIOScore extends BaseJsonService {
errorMessages: { 404: 'package not found or too new' },
})
const score = type === 'final' ? json.score.final : json.score.detail[type]
const scoreType = type.slice(0, -6)
const score =
scoreType === 'final' ? json.score.final : json.score.detail[scoreType]
return this.constructor.render({ type, score })
return this.constructor.render({ type: scoreType, score })
}
}

View File

@@ -22,7 +22,7 @@ export default class PypiBase extends BaseJsonService {
static buildRoute(base) {
return {
base,
pattern: ':egg*',
pattern: ':egg+',
}
}

View File

@@ -50,7 +50,7 @@ export default class PypiFrameworkVersion extends PypiBase {
base: 'pypi/frameworkversions',
pattern: `:frameworkName(${Object.keys(frameworkNameMap).join(
'|'
)})/:packageName*`,
)})/:packageName+`,
}
static examples = [

View File

@@ -31,8 +31,7 @@ export default class SonarFortifyRating extends SonarBase {
},
staticPreview: this.render({ rating: 4 }),
keywords,
documentation: `
<p>
documentation: `<p>
Note that the Fortify Security Rating badge will only work on Sonar instances that have the <a href='https://marketplace.microfocus.com/fortify/content/fortify-sonarqube-plugin'>Fortify SonarQube Plugin</a> installed.
The badge is not available for projects analyzed on SonarCloud.io
</p>

View File

@@ -47,15 +47,14 @@ const queryParamWithFormatSchema = Joi.object({
}).required()
const keywords = ['sonarcloud', 'sonarqube']
const documentation = `
<p>
const documentation = `<p>
The Sonar badges will work with both SonarCloud.io and self-hosted SonarQube instances.
Just enter the correct protocol and path for your target Sonar deployment.
</p>
<p>
If you are targeting a legacy SonarQube instance that is version 5.3 or earlier, then be sure
to include the version query parameter with the value of your SonarQube version.
</p
</p>
`
export {

View File

@@ -43,8 +43,7 @@ class SonarTestsSummary extends SonarBase {
isCompact: false,
}),
keywords,
documentation: `
${documentation}
documentation: `${documentation}
${testResultsDocumentation}
`,
},

View File

@@ -1,15 +1,73 @@
import { escapeFormat } from '../../core/badge-urls/path-helpers.js'
import { BaseStaticService } from '../index.js'
const description = `<p>
The static badge accepts a single required path parameter which encodes either:
</p>
<ul>
<li>
Label, message and color seperated by a dash <code>-</code>. For example:<br />
<img alt="any text: you like" src="https://img.shields.io/badge/any_text-you_like-blue" /> -
<a href="https://img.shields.io/badge/any_text-you_like-blue">https://img.shields.io/badge/any_text-you_like-blue</a>
</li>
<li>
Message and color only, seperated by a dash <code>-</code>. For example:<br />
<img alt="just the message" src="https://img.shields.io/badge/just%20the%20message-8A2BE2" /> -
<a href="https://img.shields.io/badge/just%20the%20message-8A2BE2">https://img.shields.io/badge/just%20the%20message-8A2BE2</a>
</li>
</ul>
<table>
<tbody>
<tr>
<th>URL input</th>
<th>Badge output</th>
</tr>
<tr>
<td>Underscore <code>_</code> or <code>%20</code></td>
<td>Space <code>&nbsp;</code></td>
</tr>
<tr>
<td>Double underscore <code>__</code></td>
<td>Underscore <code>_</code></td>
</tr>
<tr>
<td>Double dash <code>--</code></td>
<td>Dash <code>-</code></td>
</tr>
</tbody>
</table>
<p>
Hex, rgb, rgba, hsl, hsla and css named colors may be used.
</p>`
export default class StaticBadge extends BaseStaticService {
static category = 'static'
static route = {
base: '',
format: '(?::|badge/)((?:[^-]|--)*?)-?((?:[^-]|--)*)-((?:[^-.]|--)+)',
capture: ['label', 'message', 'color'],
}
static openApi = {
'/badge/{badgeContent}': {
get: {
summary: 'Static Badge',
description,
parameters: [
{
name: 'badgeContent',
description:
'Label, (optional) message, and color. Seperated by dashes',
in: 'path',
required: true,
schema: { type: 'string' },
example: 'build-passing-brightgreen',
},
],
},
},
}
handle({ label, message, color }) {
return { label: escapeFormat(label), message: escapeFormat(message), color }
}

View File

@@ -0,0 +1,17 @@
import { InvalidResponse } from '../index.js'
export function parseVersionFromVcpkgManifest(manifest) {
if (manifest['version-date']) {
return manifest['version-date']
}
if (manifest['version-semver']) {
return manifest['version-semver']
}
if (manifest['version-string']) {
return manifest['version-string']
}
if (manifest.version) {
return manifest.version
}
throw new InvalidResponse({ prettyMessage: 'missing version' })
}

View File

@@ -0,0 +1,41 @@
import { expect } from 'chai'
import { InvalidResponse } from '../index.js'
import { parseVersionFromVcpkgManifest } from './vcpkg-version-helpers.js'
describe('parseVersionFromVcpkgManifest', function () {
it('returns a version when `version` field is detected', function () {
expect(
parseVersionFromVcpkgManifest({
version: '2.12.1',
})
).to.equal('2.12.1')
})
it('returns a version when `version-date` field is detected', function () {
expect(
parseVersionFromVcpkgManifest({
'version-date': '2022-12-04',
})
).to.equal('2022-12-04')
})
it('returns a version when `version-semver` field is detected', function () {
expect(
parseVersionFromVcpkgManifest({
'version-semver': '3.11.2',
})
).to.equal('3.11.2')
})
it('returns a version when `version-date` field is detected', function () {
expect(
parseVersionFromVcpkgManifest({
'version-string': '22.01',
})
).to.equal('22.01')
})
it('rejects when no version field variant is detected', function () {
expect(() => parseVersionFromVcpkgManifest('{}')).to.throw(InvalidResponse)
})
})

View File

@@ -3,10 +3,26 @@ import { ConditionalGithubAuthV3Service } from '../github/github-auth-service.js
import { fetchJsonFromRepo } from '../github/github-common-fetch.js'
import { renderVersionBadge } from '../version.js'
import { NotFound } from '../index.js'
import { parseVersionFromVcpkgManifest } from './vcpkg-version-helpers.js'
const vcpkgManifestSchema = Joi.object({
version: Joi.string().required(),
}).required()
// Handle the different version fields available in Vcpkg manifests
// https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json?source=recommendations#version
const vcpkgManifestSchema = Joi.alternatives()
.match('one')
.try(
Joi.object({
version: Joi.string().required(),
}).required(),
Joi.object({
'version-date': Joi.string().required(),
}).required(),
Joi.object({
'version-semver': Joi.string().required(),
}).required(),
Joi.object({
'version-string': Joi.string().required(),
}).required()
)
export default class VcpkgVersion extends ConditionalGithubAuthV3Service {
static category = 'version'
@@ -29,13 +45,14 @@ export default class VcpkgVersion extends ConditionalGithubAuthV3Service {
async handle({ portName }) {
try {
const { version } = await fetchJsonFromRepo(this, {
const manifest = await fetchJsonFromRepo(this, {
schema: vcpkgManifestSchema,
user: 'microsoft',
repo: 'vcpkg',
branch: 'master',
filename: `ports/${portName}/vcpkg.json`,
})
const version = parseVersionFromVcpkgManifest(manifest)
return this.constructor.render({ version })
} catch (error) {
if (error instanceof NotFound) {

View File

@@ -3,11 +3,11 @@ import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('gets the port version of entt')
.get('/entt.json')
.expectBadge({ label: 'vcpkg', message: isSemver })
t.create('gets nlohmann-json port version')
.get('/nlohmann-json.json')
.expectBadge({ label: 'vcpkg', color: 'blue', message: isSemver })
t.create('returns not found for invalid port')
t.create('gets not found error for invalid port')
.get('/this-port-does-not-exist.json')
.expectBadge({
label: 'vcpkg',

View File

@@ -16,7 +16,7 @@ const extensionQuerySchema = Joi.object({
value: Joi.number().required(),
})
)
.required(),
.default([]),
versions: Joi.array()
.items(
Joi.object({

View File

@@ -101,6 +101,35 @@ t.create('zero installs')
color: 'red',
})
t.create('missing statistics array')
.get('/visual-studio-marketplace/i/swellaby.rust-pack.json')
.intercept(nock =>
nock('https://marketplace.visualstudio.com/_apis/public/gallery/')
.post('/extensionquery/')
.reply(200, {
results: [
{
extensions: [
{
versions: [
{
version: '1.0.0',
},
],
releaseDate: '2019-04-13T07:50:27.000Z',
lastUpdated: '2019-04-13T07:50:27.000Z',
},
],
},
],
})
)
.expectBadge({
label: 'installs',
message: '0',
color: 'red',
})
t.create('downloads')
.get('/visual-studio-marketplace/d/swellaby.rust-pack.json')
.intercept(nock =>