Compare commits

...

493 Commits

Author SHA1 Message Date
Marcin Mielnicki
068d5606e9 Redirect to a static badge instead of returning status code 500 2019-10-27 18:38:21 +01:00
Marcin Mielnicki
824d6de448 Redirect to a static badge instead of returning status code 500 2019-10-27 18:35:14 +01:00
Marcin Mielnicki
5b15c01866 Redirector should return status code 500 when redirect URL is invalid 2019-10-24 19:11:02 +02:00
Oshawk
a607673ad0 Add GitLab pipline suggestion (#4226)
* Add GitLab pipline suggestion

Added a suggestion for a pipeline badge when a GitLab URL is entered.

* Add tests

Added tests for the GitLab badge suggestion.

* Fix tests

Fixed the tests.
2019-10-23 13:25:26 -05:00
seetd
54bcedc0f4 Add [W3C] Markup Validation Service Badge (#3833) (#4148)
* Add W3C Markup Validation Service Badge (#3833)

* Move helper functions into different file and added unit tests

* Remove unnecessary comments from spec file

* pr changes move code into transform method and validation of messages

* use joi.string().regex instead of custom validator

* Simplify the fetch, handle methods. Make Joi validation for string

* Remove empty parameter from tests and label from render method

* encodeUri on the doc and schema properties send to API

* Documentation and remove unnecessary Object.keys call

* Use regular expressions to make tests less brittle

* made service less for message and color more generic and less brittle

* Throw standard NoFound exception for invalid URL. Use w3c endpoint

* use sazerac for w3c-validation-helper.spec.js

* Replace documentation API url and API documentation url

* Switch back to https://validator.nu endpoint. Remove html4 assertions

* Increase strictness of NotFound checks
2019-10-21 18:40:14 -05:00
Michael Schmitz
f82f7b798d [gitlab] Add documentation for publicity state of pipelines (#4218)
* Add documentation for publicity state of pipelines

* Modify visual picture to be smaller and add red circle to mark important setting

* Adapt suggestion

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>
2019-10-20 12:14:55 -05:00
dependabot-preview[bot]
3ceede8f1d Build(deps-dev): bump gatsby-plugin-react-helmet from 3.1.11 to 3.1.13 (#4213)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-react-helmet) from 3.1.11 to 3.1.13.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.1.13/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 16:52:58 -05:00
dependabot-preview[bot]
5142bf299f Build(deps-dev): bump babel-preset-gatsby from 0.2.18 to 0.2.20 (#4216)
Bumps [babel-preset-gatsby](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/babel-preset-gatsby) from 0.2.18 to 0.2.20.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-preset-gatsby/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/babel-preset-gatsby@0.2.20/packages/babel-preset-gatsby)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 16:17:05 +00:00
dependabot-preview[bot]
f298564f72 Build(deps-dev): bump gatsby-plugin-remove-trailing-slashes (#4215)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-remove-trailing-slashes) from 2.1.10 to 2.1.12.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.1.12/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 16:02:31 +00:00
dependabot-preview[bot]
3a42a61862 Build(deps-dev): bump gatsby-plugin-catch-links from 2.1.12 to 2.1.15 (#4212)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-catch-links) from 2.1.12 to 2.1.15.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.1.15/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 15:47:54 +00:00
dependabot-preview[bot]
d34118315b Build(deps): bump dotenv from 8.1.0 to 8.2.0 (#4209)
Bumps [dotenv](https://github.com/motdotla/dotenv) from 8.1.0 to 8.2.0.
- [Release notes](https://github.com/motdotla/dotenv/releases)
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/motdotla/dotenv/compare/v8.1.0...v8.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 15:15:46 +00:00
dependabot-preview[bot]
d83601c57b Build(deps-dev): bump @types/node from 12.7.11 to 12.11.1 (#4214)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 12.7.11 to 12.11.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 15:00:35 +00:00
dependabot-preview[bot]
d1fcb659d8 Build(deps-dev): bump typescript from 3.6.3 to 3.6.4 (#4211)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.6.3 to 3.6.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v3.6.3...v3.6.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 14:46:00 +00:00
dependabot-preview[bot]
123f17ea20 Build(deps-dev): bump nodemon from 1.19.3 to 1.19.4 (#4210)
Bumps [nodemon](https://github.com/remy/nodemon) from 1.19.3 to 1.19.4.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v1.19.3...v1.19.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 14:31:28 +00:00
dependabot-preview[bot]
a90cc7871d Build(deps-dev): bump concurrently from 4.1.2 to 5.0.0 (#4201)
Bumps [concurrently](https://github.com/kimmobrunfeldt/concurrently) from 4.1.2 to 5.0.0.
- [Release notes](https://github.com/kimmobrunfeldt/concurrently/releases)
- [Commits](https://github.com/kimmobrunfeldt/concurrently/compare/v4.1.2...v5.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-19 14:16:57 +00:00
dependabot-preview[bot]
8a21c7746f Build(deps-dev): bump gatsby-plugin-page-creator from 2.1.24 to 2.1.27 (#4207)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-page-creator) from 2.1.24 to 2.1.27.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.1.27/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 17:59:47 -05:00
dependabot-preview[bot]
7da6c3f98e Build(deps-dev): bump lint-staged from 9.4.1 to 9.4.2 (#4208)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 9.4.1 to 9.4.2.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v9.4.1...v9.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 17:05:51 -05:00
dependabot-preview[bot]
627beab837 Build(deps-dev): bump gatsby from 2.15.36 to 2.16.5 (#4205)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.15.36 to 2.16.5.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.15.36...gatsby@2.16.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 15:31:32 -05:00
dependabot-preview[bot]
663a2a36e0 Build(deps-dev): bump gatsby-plugin-styled-components (#4202)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-styled-components) from 3.1.8 to 3.1.11.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.1.11/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 20:13:02 +00:00
Caleb Cartwright
68c8b94d0c tests: fix CodeClimate Analysis service tests (#4191) 2019-10-18 13:33:12 -05:00
dependabot-preview[bot]
d0c5a599b1 Build(deps-dev): bump snap-shot-it from 7.8.0 to 7.9.0 (#4206)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 7.8.0 to 7.9.0.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v7.8.0...v7.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 13:26:32 -05:00
dependabot-preview[bot]
9d32aed46f Build(deps-dev): bump start-server-and-test from 1.10.5 to 1.10.6 (#4204)
Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.10.5 to 1.10.6.
- [Release notes](https://github.com/bahmutov/start-server-and-test/releases)
- [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.10.5...v1.10.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 17:18:04 +00:00
Caleb Cartwright
c71e9fe007 tests: fix aur license test (#4192) 2019-10-18 12:01:14 -05:00
dependabot-preview[bot]
e6adf8d2a5 Build(deps-dev): bump eslint-plugin-mocha from 6.1.1 to 6.2.0 (#4200)
Bumps [eslint-plugin-mocha](https://github.com/lo1tuma/eslint-plugin-mocha) from 6.1.1 to 6.2.0.
- [Release notes](https://github.com/lo1tuma/eslint-plugin-mocha/releases)
- [Changelog](https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lo1tuma/eslint-plugin-mocha/compare/6.1.1...6.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 11:48:42 -05:00
dependabot-preview[bot]
bb081423dd Build(deps): bump @sentry/node from 5.7.0 to 5.7.1 (#4203)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 5.7.0 to 5.7.1.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/5.7.0...5.7.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 11:33:51 -05:00
dependabot-preview[bot]
eac016b969 Build(deps-dev): bump enzyme-adapter-react-16 from 1.14.0 to 1.15.1 (#4199)
Bumps [enzyme-adapter-react-16](https://github.com/airbnb/enzyme/tree/HEAD/packages/enzyme-adapter-react-16) from 1.14.0 to 1.15.1.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/commits/enzyme-adapter-react-16@1.15.1/packages/enzyme-adapter-react-16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 11:20:02 -05:00
dependabot-preview[bot]
0b6e1efe5e Build(deps-dev): bump gatsby-plugin-typescript from 2.1.11 to 2.1.15 (#4198)
Bumps [gatsby-plugin-typescript](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-typescript) from 2.1.11 to 2.1.15.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-typescript/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-typescript@2.1.15/packages/gatsby-plugin-typescript)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 10:30:32 -05:00
dependabot-preview[bot]
7a7bf66233 Build(deps-dev): bump portfinder from 1.0.24 to 1.0.25 (#4197)
Bumps [portfinder](https://github.com/indexzero/node-portfinder) from 1.0.24 to 1.0.25.
- [Release notes](https://github.com/indexzero/node-portfinder/releases)
- [Commits](https://github.com/indexzero/node-portfinder/compare/v1.0.24...v1.0.25)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 10:07:48 -05:00
dependabot-preview[bot]
49a5283702 Build(deps-dev): bump eslint-plugin-jsdoc from 15.9.9 to 15.12.0 (#4196)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 15.9.9 to 15.12.0.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v15.9.9...v15.12.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 09:55:23 -05:00
dependabot-preview[bot]
3c5c35b309 Build(deps-dev): bump @types/react-helmet from 5.0.11 to 5.0.12 (#4195)
Bumps [@types/react-helmet](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-helmet) from 5.0.11 to 5.0.12.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 09:42:49 -05:00
Michael Schmitz
c729ef8ece Adjust new [swagger] endpoint (#4193)
* Change to new Url supporting OAS 3

* Change to new URL
2019-10-18 09:10:57 -05:00
dependabot-preview[bot]
0cb19e692b Build(deps-dev): bump husky from 3.0.8 to 3.0.9 (#4194)
Bumps [husky](https://github.com/typicode/husky) from 3.0.8 to 3.0.9.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v3.0.8...v3.0.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 08:39:31 -05:00
Joe Clay
62bee16975 Add Crates.io recent downloads badge (fixes #4186), run [Crates] (#4187)
* Add Crates.io recent downloads badge (fixes #4186)

* Rename extractDownloads to transform

* Fix up the error handling a bit

* Simplify imports
2019-10-17 14:46:10 -05:00
Tagan Hoyle
7b3073149c Refactor [wordpress] downloads and add interval to theme downloads (#4180)
Refactor wordpress downloads service
Also add interval for theme downloads
2019-10-15 19:29:00 +01:00
Max Rydahl Andersen
0862ae2665 Bump(deps-dev): bump to simple-icons 1.18 (#4175) (#4179)
To get Quarkus icon :)
2019-10-14 18:24:36 -05:00
Marcin Mielnicki
cef6c3134d 3 retries for service tests on CI (#4176) 2019-10-14 21:08:17 +02:00
Caleb Cartwright
8b95cdc2aa refactor: honor build qualifiers in version comparisons (#4173) 2019-10-14 12:43:55 -05:00
Caleb Cartwright
13d1cbe0f9 tests: fix service test for ubuntu (#4174) 2019-10-14 18:13:10 +02:00
Tagan Hoyle
b8d0ec4238 Add CORS Header to every request (#4171)
* Try enable universal cors

* Move handle from registerErrorHandlers because it isn't and error handler

* Add test for cors headers

Also add link to issue
2019-10-13 18:51:15 -05:00
Marcin Mielnicki
2c39ee489a An option to retry a failed service; test on [dynamicxml] (#4166)
* An option to retry a failed service test

* Convert retry options to integers

* Info about the unit

* JSDoc for retry configuraion
2019-10-13 18:09:46 +02:00
Pierre-Yves B
0439e10ac8 Support [JenkinsCoverage] through the Code Coverage API plugin (#4168) 2019-10-12 18:24:29 +01:00
Marcin Mielnicki
4c159eff00 Support for XPath functions in [dynamicxml] badge (#4153)
* Support XPath query with type convertion

* Support XPath query with node function

* Parametrized tests for transform function

* Handle unusual values returned by 'select'
2019-10-12 17:23:17 +02:00
dependabot-preview[bot]
3a6611b199 Build(deps-dev): bump gatsby from 2.15.29 to 2.15.36 (#4165)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.15.29 to 2.15.36.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.15.29...gatsby@2.15.36)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 14:49:26 -05:00
dependabot-preview[bot]
af558e7235 Build(deps-dev): bump @babel/core from 7.6.2 to 7.6.4 (#4164)
Bumps [@babel/core](https://github.com/babel/babel) from 7.6.2 to 7.6.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.6.2...v7.6.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 14:22:33 -05:00
dependabot-preview[bot]
9210f2b394 Build(deps-dev): bump nock from 11.3.5 to 11.4.0 (#4163)
Bumps [nock](https://github.com/nock/nock) from 11.3.5 to 11.4.0.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/compare/v11.3.5...v11.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 14:10:37 -05:00
dependabot-preview[bot]
9515352b0a Build(deps-dev): bump gatsby-plugin-react-helmet from 3.1.10 to 3.1.11 (#4162)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-react-helmet) from 3.1.10 to 3.1.11.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.1.11/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 13:54:13 -05:00
dependabot-preview[bot]
32f0f06a2d Build(deps-dev): bump gatsby-plugin-remove-trailing-slashes (#4161)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-remove-trailing-slashes) from 2.1.9 to 2.1.10.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.1.10/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 13:43:56 -05:00
dependabot-preview[bot]
b7943b5b9f Build(deps-dev): bump babel-preset-gatsby from 0.2.17 to 0.2.18 (#4160)
Bumps [babel-preset-gatsby](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/babel-preset-gatsby) from 0.2.17 to 0.2.18.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-preset-gatsby/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/babel-preset-gatsby@0.2.18/packages/babel-preset-gatsby)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 13:32:56 -05:00
dependabot-preview[bot]
242e03395d Build(deps-dev): bump react-pose from 4.0.8 to 4.0.9 (#4159)
Bumps [react-pose](https://github.com/Popmotion/popmotion) from 4.0.8 to 4.0.9.
- [Release notes](https://github.com/Popmotion/popmotion/releases)
- [Commits](https://github.com/Popmotion/popmotion/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 13:23:24 -05:00
dependabot-preview[bot]
8a7041ec7c Build(deps-dev): bump @babel/preset-env from 7.6.2 to 7.6.3 (#4158)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.6.2 to 7.6.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.6.2...v7.6.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 13:14:33 -05:00
dependabot-preview[bot]
2c52139e28 Build(deps): bump @hapi/joi from 16.1.5 to 16.1.7 (#4157)
Bumps [@hapi/joi](https://github.com/hapijs/joi) from 16.1.5 to 16.1.7.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hapijs/joi/compare/v16.1.5...v16.1.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 13:01:08 -05:00
dependabot-preview[bot]
7848618bb1 Build(deps-dev): bump eslint-config-prettier from 6.3.0 to 6.4.0 (#4156)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 6.3.0 to 6.4.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v6.3.0...v6.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 12:44:59 -05:00
dependabot-preview[bot]
38f27b1e30 Build(deps-dev): bump start-server-and-test from 1.10.4 to 1.10.5 (#4155)
Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.10.4 to 1.10.5.
- [Release notes](https://github.com/bahmutov/start-server-and-test/releases)
- [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.10.4...v1.10.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 12:29:11 -05:00
dependabot-preview[bot]
a640573c89 Build(deps): bump @sentry/node from 5.6.2 to 5.7.0 (#4154)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 5.6.2 to 5.7.0.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/5.6.2...5.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-11 11:55:56 -05:00
netsgnut
76665f6b42 Allow [librariesio] badges referencing scoped npm package (#4025) (#4151)
* Allow libraries.io badges referencing scoped npm package (#4025)

* Set timeout of all libraries.io test units to 10s
2019-10-11 08:56:01 -05:00
Kamontat Chantrachirathumrong
2119a01953 fix invalid link (#4152) 2019-10-10 08:37:21 -05:00
Caleb Cartwright
65f66642dd fix type errors in [DynamicXml] service (#4041)
* fix: type errors in DynamicXml service

* tests: add more tests for DynamicXml

* tests: another DynamicXml service test
2019-10-08 15:48:43 -05:00
chris48s
a66e4f9e10 change query for fork count (#4150) 2019-10-08 19:15:29 +01:00
Caleb Cartwright
e9860aefbc update contributing docs on url/query params (#4141)
* doc: update contribitung docs on url/query params

* chore: minor doc tweaks
2019-10-07 12:28:55 +00:00
Caleb Cartwright
b05f0e8d0b Update service tests for [Scrutinizer Microbadger jsDelivr] (#4145)
* fix: support scrutinizer branches with only failed builds

* tests: increase timeout for microbadger tests

* tests: increase timeouts for jsdelivr and microbadger tests
2019-10-07 07:19:07 -05:00
Paul Melnikow
dde66ca383 Fix tests in Node 12 (#4146)
c.f. https://github.com/badges/shields/pull/4145#issuecomment-538768061

This is super-strange. I am curious what this is about! (Though not quite curious enough to go digging.)

The test failure is reproducible in Node 12.11.0 though not e.g. 10.6.3.

Example failure on master: https://circleci.com/gh/badges/shields/74325
2019-10-06 16:12:22 -04:00
Caleb Cartwright
65b54e0420 handle missing license key in [aur] (#4143)
* fix: handle missing license key in aur

* refactor: improve missing license message
2019-10-06 09:17:49 -05:00
dependabot-preview[bot]
b7235981c6 Build(deps-dev): bump gatsby-plugin-page-creator from 2.1.23 to 2.1.24 (#4137)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-page-creator) from 2.1.23 to 2.1.24.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.1.24/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-05 11:47:10 -05:00
dependabot-preview[bot]
6dd5b5981f Build(deps-dev): bump gatsby from 2.15.28 to 2.15.29 (#4132)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.15.28 to 2.15.29.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.15.28...gatsby@2.15.29)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-05 11:38:29 -05:00
dependabot-preview[bot]
3897fb916b Build(deps-dev): bump @types/react-select from 3.0.4 to 3.0.5 (#4134)
Bumps [@types/react-select](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-select) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-select)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-05 11:30:12 -05:00
dependabot-preview[bot]
41ea753520 Build(deps-dev): bump react-error-overlay from 6.0.2 to 6.0.3 (#4131)
Bumps [react-error-overlay](https://github.com/facebook/create-react-app/tree/HEAD/packages/react-error-overlay) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/facebook/create-react-app/releases)
- [Changelog](https://github.com/facebook/create-react-app/blob/master/CHANGELOG-1.x.md)
- [Commits](https://github.com/facebook/create-react-app/commits/react-error-overlay@6.0.3/packages/react-error-overlay)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-05 11:21:25 -05:00
dependabot-preview[bot]
88d4f4fbee Build(deps-dev): bump react-dom from 16.9.0 to 16.10.2 (#4130)
Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.9.0 to 16.10.2.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.10.2/packages/react-dom)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-05 11:11:49 -05:00
dependabot-preview[bot]
8310f63b66 Build(deps-dev): bump react from 16.9.0 to 16.10.2 (#4125)
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.9.0 to 16.10.2.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.10.2/packages/react)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-05 11:01:45 -05:00
dependabot-preview[bot]
d8492cc985 Build(deps-dev): bump react-select from 3.0.5 to 3.0.8 (#4124)
Bumps [react-select](https://github.com/JedWatson/react-select) from 3.0.5 to 3.0.8.
- [Release notes](https://github.com/JedWatson/react-select/releases)
- [Changelog](https://github.com/JedWatson/react-select/blob/master/.sweet-changelogs.js)
- [Commits](https://github.com/JedWatson/react-select/compare/react-select@3.0.5...react-select@3.0.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-05 10:28:33 -05:00
dependabot-preview[bot]
96b02f0377 Build(deps): bump @hapi/joi from 16.1.4 to 16.1.5 (#4123)
Bumps [@hapi/joi](https://github.com/hapijs/joi) from 16.1.4 to 16.1.5.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hapijs/joi/compare/v16.1.4...v16.1.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 22:13:36 +00:00
dependabot-preview[bot]
11836f55de Build(deps): bump fast-xml-parser from 3.12.20 to 3.13.0 (#4138)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.20 to 3.13.0.
- [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/3.12.20...3.13.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 21:37:22 +00:00
dependabot-preview[bot]
8129ff598a Build(deps): bump cross-env from 6.0.0 to 6.0.3 (#4126)
Bumps [cross-env](https://github.com/kentcdodds/cross-env) from 6.0.0 to 6.0.3.
- [Release notes](https://github.com/kentcdodds/cross-env/releases)
- [Changelog](https://github.com/kentcdodds/cross-env/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kentcdodds/cross-env/compare/v6.0.0...v6.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 21:25:51 +00:00
seetd
f5823241f2 Add documentation for Discord badge (#3952) (#4117) 2019-10-04 22:10:52 +01:00
dependabot-preview[bot]
989293b885 Build(deps-dev): bump nodemon from 1.19.2 to 1.19.3 (#4135)
Bumps [nodemon](https://github.com/remy/nodemon) from 1.19.2 to 1.19.3.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v1.19.2...v1.19.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 21:00:25 +00:00
dependabot-preview[bot]
3e2fa09b92 Build(deps-dev): bump eslint-plugin-react from 7.14.3 to 7.16.0 (#4136)
* Build(deps-dev): bump eslint-plugin-react from 7.14.3 to 7.16.0

Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.14.3 to 7.16.0.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.14.3...v7.16.0)

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

* appease the lint gods 🙏
2019-10-04 20:20:08 +00:00
dependabot-preview[bot]
f433a317e6 Build(deps-dev): bump start-server-and-test from 1.10.2 to 1.10.4 (#4133)
Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.10.2 to 1.10.4.
- [Release notes](https://github.com/bahmutov/start-server-and-test/releases)
- [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.10.2...v1.10.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 20:03:45 +00:00
dependabot-preview[bot]
ebf31387c3 Build(deps-dev): bump eslint-plugin-react-hooks from 2.0.1 to 2.1.2 (#4128)
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 2.0.1 to 2.1.2.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 19:43:36 +00:00
dependabot-preview[bot]
3e293b935f Build(deps-dev): bump lint-staged from 9.4.0 to 9.4.1 (#4129)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 9.4.0 to 9.4.1.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v9.4.0...v9.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 19:13:40 +00:00
dependabot-preview[bot]
cbe5b4aac8 Build(deps): bump config from 3.2.2 to 3.2.3 (#4120)
Bumps [config](https://github.com/lorenwest/node-config) from 3.2.2 to 3.2.3.
- [Release notes](https://github.com/lorenwest/node-config/releases)
- [Changelog](https://github.com/lorenwest/node-config/blob/master/History.md)
- [Commits](https://github.com/lorenwest/node-config/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 18:50:24 +00:00
dependabot-preview[bot]
663f727a5e Build(deps-dev): bump @types/node from 12.7.8 to 12.7.11 (#4122)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 12.7.8 to 12.7.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 18:33:54 +00:00
dependabot-preview[bot]
38cae6c4b7 Build(deps-dev): bump eslint-plugin-jsdoc from 15.9.4 to 15.9.9 (#4121)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 15.9.4 to 15.9.9.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v15.9.4...v15.9.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 18:09:39 +00:00
dependabot-preview[bot]
c7c0550b1f Build(deps-dev): bump husky from 3.0.5 to 3.0.8 (#4127)
Bumps [husky](https://github.com/typicode/husky) from 3.0.5 to 3.0.8.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v3.0.5...v3.0.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 17:23:59 +00:00
dependabot-preview[bot]
c51ba324a9 Build(deps-dev): bump mocha from 6.2.0 to 6.2.1 (#4119)
Bumps [mocha](https://github.com/mochajs/mocha) from 6.2.0 to 6.2.1.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.2.0...v6.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 11:57:07 -05:00
Marcin Mielnicki
274dfea9a8 Missing spaces added do the usage section (#4116) 2019-10-03 22:31:50 +02:00
Caleb Cartwright
5f0253ae5c chore: add hacktoberfest badge :) (#4115) 2019-10-03 08:57:33 -05:00
Paul Melnikow
76cb943858 Add a GitHub project badge for Hacktoberfest [GithubHacktoberfest] (#4109) 2019-10-02 22:05:56 -04:00
Paul Melnikow
33a6c5398d Fix an undefined variable in [GithubPackageJson] (#4113)
* Fix an undefined variable in [GithubPackageJson]

Make sure this gets linted in the future.

* Run prettier
2019-10-02 21:26:12 +00:00
Paul Melnikow
a5b2f5436c Optimize [GithubIssues] using GraphQL (#4107)
While playing around with a badge for Hacktoberfest I noticed the GitHub Issues badge fetches a huge amount of JSON to render just the total count. There doesn’t seem to be a way to limit the response size through the REST API, so I thought I’d switch this to use GraphQL instead.
2019-10-02 19:34:14 +00:00
Paul Melnikow
e8d49f2504 Add dependency badge for Pipenv applications [GithubPipenv] (#4096)
I recently published https://github.com/metabolize/rq-dashboard-on-heroku and want to add badges to show the locked version of Python and rq-dashboard, the main dependency it’s wrapping.

This is along the lines of #2259, which was for package.json-based applications, and also included some discussion of a Python application that used `requirements.txt`. It’s useful for showing the pinned version of any dependency in a Python application that uses a lockfile.

In the future, as an alternative to reading Pipfile.lock, I could see expanding this to read Pipfile. However for my purposes I prefer to show the locked dependency, since that’s the version that a user of my package would actually get if they ran it on Heroku.
2019-10-02 15:24:14 -04:00
Pierre-Yves B
157a6180b2 Make search work with category names (#4103) 2019-10-02 20:03:59 +01:00
seetd
a865b81acb fix: allow empty but required resolution property for [Bugzilla] (#4102) (#4106)
* fix: use repos from badges organization for GithubContributors  (#4104)

* fix: allow empty but required resolution property for [Bugzilla] (#4102)
2019-10-02 12:11:40 -05:00
seetd
51d879d7d2 fix: use repos from badges organization for GithubContributors (#4104) (#4105)
Fixes #4104
2019-10-02 00:21:46 -05:00
dependabot-preview[bot]
362da5262b Build(deps-dev): bump @types/react-helmet from 5.0.10 to 5.0.11 (#4094)
Bumps [@types/react-helmet](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-helmet) from 5.0.10 to 5.0.11.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-01 19:29:33 +02:00
dependabot-preview[bot]
9286d4c144 Build(deps-dev): bump gatsby from 2.15.15 to 2.15.28 (#4080)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.15.15 to 2.15.28.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.15.15...gatsby@2.15.28)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-01 08:14:50 -05:00
dependabot-preview[bot]
30df257abf Build(deps-dev): bump styled-components from 4.3.2 to 4.4.0 (#4073)
Bumps [styled-components](https://github.com/styled-components/styled-components) from 4.3.2 to 4.4.0.
- [Release notes](https://github.com/styled-components/styled-components/releases)
- [Changelog](https://github.com/styled-components/styled-components/blob/master/CHANGELOG.md)
- [Commits](https://github.com/styled-components/styled-components/compare/v4.3.2...v4.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-01 07:57:56 -05:00
dependabot-preview[bot]
995408a419 Build(deps-dev): bump gatsby-plugin-styled-components (#4092)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-styled-components) from 3.1.6 to 3.1.8.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.1.8/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-01 12:12:32 +00:00
dependabot-preview[bot]
6d23384f5d Build(deps-dev): bump @types/node from 12.7.5 to 12.7.8 (#4089)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 12.7.5 to 12.7.8.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-29 00:19:04 +00:00
dependabot-preview[bot]
b4ac9cc7ee Build(deps-dev): bump gatsby-plugin-typescript from 2.1.9 to 2.1.11 (#4086)
Bumps [gatsby-plugin-typescript](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-typescript) from 2.1.9 to 2.1.11.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-typescript/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-typescript@2.1.11/packages/gatsby-plugin-typescript)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-29 00:05:48 +00:00
dependabot-preview[bot]
2240e2bbc0 Build(deps-dev): bump gatsby-plugin-remove-trailing-slashes (#4081)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-remove-trailing-slashes) from 2.1.7 to 2.1.9.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.1.9/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-28 23:54:51 +00:00
dependabot-preview[bot]
28dd715364 Build(deps-dev): bump @babel/register from 7.6.0 to 7.6.2 (#4085)
Bumps [@babel/register](https://github.com/babel/babel) from 7.6.0 to 7.6.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.6.0...v7.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-28 18:08:49 +00:00
dependabot-preview[bot]
d8ec783030 Build(deps-dev): bump gatsby-plugin-catch-links from 2.1.10 to 2.1.12 (#4084)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-catch-links) from 2.1.10 to 2.1.12.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.1.12/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-28 18:01:35 +00:00
dependabot-preview[bot]
13200ebfcb Build(deps-dev): bump gatsby-plugin-page-creator from 2.1.21 to 2.1.23 (#4093)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-page-creator) from 2.1.21 to 2.1.23.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.1.23/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-28 16:54:26 +00:00
Caleb Cartwright
645343887e fix: add killed to drone schema (#4099) 2019-09-28 11:46:32 -05:00
dependabot-preview[bot]
be464377e1 Build(deps-dev): bump @babel/preset-env from 7.6.0 to 7.6.2 (#4077)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.6.0 to 7.6.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.6.0...v7.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 21:02:33 +00:00
dependabot-preview[bot]
08b095e57e Build(deps-dev): bump eslint-plugin-cypress from 2.6.1 to 2.7.0 (#4083)
Bumps [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress) from 2.6.1 to 2.7.0.
- [Release notes](https://github.com/cypress-io/eslint-plugin-cypress/releases)
- [Commits](https://github.com/cypress-io/eslint-plugin-cypress/compare/v2.6.1...v2.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 20:53:24 +00:00
dependabot-preview[bot]
d3a7a139e4 Build(deps): bump graphql from 14.5.6 to 14.5.8 (#4079)
Bumps [graphql](https://github.com/graphql/graphql-js) from 14.5.6 to 14.5.8.
- [Release notes](https://github.com/graphql/graphql-js/releases)
- [Commits](https://github.com/graphql/graphql-js/compare/v14.5.6...v14.5.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 20:40:38 +00:00
dependabot-preview[bot]
60428dae2a Build(deps-dev): bump @babel/core from 7.6.0 to 7.6.2 (#4078)
Bumps [@babel/core](https://github.com/babel/babel) from 7.6.0 to 7.6.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.6.0...v7.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 20:18:52 +00:00
dependabot-preview[bot]
e191f05ac4 Build(deps-dev): bump @babel/plugin-proposal-object-rest-spread (#4076)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.5.5 to 7.6.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.5.5...v7.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 19:59:06 +00:00
dependabot-preview[bot]
eb1c9f395a Build(deps-dev): bump eslint-plugin-jsdoc from 15.9.2 to 15.9.4 (#4074)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 15.9.2 to 15.9.4.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v15.9.2...v15.9.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 19:38:34 +00:00
dependabot-preview[bot]
3f8aaaaf76 Build(deps): bump @hapi/joi from 16.1.2 to 16.1.4 (#4072)
Bumps [@hapi/joi](https://github.com/hapijs/joi) from 16.1.2 to 16.1.4.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hapijs/joi/compare/v16.1.2...v16.1.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 19:23:40 +00:00
dependabot-preview[bot]
ee01bc7dce Build(deps-dev): bump nock from 11.3.4 to 11.3.5 (#4088)
Bumps [nock](https://github.com/nock/nock) from 11.3.4 to 11.3.5.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/compare/v11.3.4...v11.3.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 19:15:46 +00:00
dependabot-preview[bot]
1ae0caa827 Build(deps-dev): bump danger from 9.2.0 to 9.2.1 (#4091)
Bumps [danger](https://github.com/danger/danger-js) from 9.2.0 to 9.2.1.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/9.2.0...9.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 17:19:54 +00:00
dependabot-preview[bot]
da161a1483 Build(deps-dev): bump sinon from 7.4.2 to 7.5.0 (#4082)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.4.2 to 7.5.0.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 17:00:09 +00:00
dependabot-preview[bot]
78aced709b Build(deps-dev): bump babel-preset-gatsby from 0.2.14 to 0.2.17 (#4095)
Bumps [babel-preset-gatsby](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/babel-preset-gatsby) from 0.2.14 to 0.2.17.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-preset-gatsby/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/babel-preset-gatsby@0.2.17/packages/babel-preset-gatsby)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 16:28:33 +00:00
dependabot-preview[bot]
0b7f5b47a3 Build(deps-dev): bump gatsby-plugin-react-helmet from 3.1.8 to 3.1.10 (#4075)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-react-helmet) from 3.1.8 to 3.1.10.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.1.10/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 15:58:47 +00:00
dependabot-preview[bot]
9151152ad7 Build(deps-dev): bump lint-staged from 9.2.5 to 9.4.0 (#4087)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 9.2.5 to 9.4.0.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v9.2.5...v9.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-27 10:36:09 -05:00
Mattias Karlsson
ddbe19f6bd Update to Simple Icons 1.16.0 (#4069) 2019-09-26 15:13:25 +00:00
Caleb Cartwright
90f8ffce9e tests: add endpoint test for #3780 (#4067) 2019-09-23 23:51:43 -04:00
chris48s
c762d971b4 upgrade Joi and related packages (#4060)
* update dependencies

* (core) children --> keys

* (core) fix/update BaseService validate

* (core) update error messages in tests

* (core) only Joi.attempt if we've got a Joi schema

* (core) allow 'expected' to be a regex

* (services) pass 2 schema to .alternatives()

* (services) functions --> Joi schema

* (services) update expected error message

* (services) explicit check for color: undefined

* re-bump joi

* (services) wrap another regex

* (core/services) remove use of array arguments

* (core/services) when --> conditional

* (services) remove more array arguments

* fix spelling in var name

* DRY up sonar helper
2019-09-23 17:36:56 +01:00
Caleb Cartwright
d18d4218fc support basic auth with just pass token (#4063)
* feat: support basic auth with token

* refactor: change param name
2019-09-22 11:14:01 -05:00
dependabot-preview[bot]
7e0ae39a20 Build(deps-dev): bump gatsby-plugin-page-creator from 2.1.17 to 2.1.21 (#4062)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-page-creator) from 2.1.17 to 2.1.21.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.1.21/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-21 14:42:13 -05:00
dependabot-preview[bot]
5931273a7c Build(deps-dev): bump react-select from 3.0.4 to 3.0.5 (#4056)
Bumps [react-select](https://github.com/JedWatson/react-select) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/JedWatson/react-select/releases)
- [Changelog](https://github.com/JedWatson/react-select/blob/master/.sweet-changelogs.js)
- [Commits](https://github.com/JedWatson/react-select/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 19:15:59 +00:00
dependabot-preview[bot]
f12b54b0dc Build(deps-dev): bump gatsby-plugin-catch-links from 2.1.9 to 2.1.10 (#4059)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-catch-links) from 2.1.9 to 2.1.10.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.1.10/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 19:08:51 +00:00
dependabot-preview[bot]
b09fc27323 Build(deps): bump cross-env from 5.2.1 to 6.0.0 (#4052)
Bumps [cross-env](https://github.com/kentcdodds/cross-env) from 5.2.1 to 6.0.0.
- [Release notes](https://github.com/kentcdodds/cross-env/releases)
- [Changelog](https://github.com/kentcdodds/cross-env/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kentcdodds/cross-env/compare/v5.2.1...v6.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 18:47:48 +00:00
dependabot-preview[bot]
3780e53d61 Build(deps-dev): bump babel-preset-gatsby from 0.2.13 to 0.2.14 (#4058)
Bumps [babel-preset-gatsby](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/babel-preset-gatsby) from 0.2.13 to 0.2.14.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-preset-gatsby/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/babel-preset-gatsby@0.2.14/packages/babel-preset-gatsby)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 18:28:19 +00:00
dependabot-preview[bot]
595078922c Build(deps-dev): bump gatsby-plugin-typescript from 2.1.7 to 2.1.9 (#4057)
Bumps [gatsby-plugin-typescript](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-typescript) from 2.1.7 to 2.1.9.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-typescript/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-typescript@2.1.9/packages/gatsby-plugin-typescript)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 18:05:46 +00:00
dependabot-preview[bot]
5bf398df0f Build(deps-dev): bump node-mocks-http from 1.7.6 to 1.8.0 (#4055)
Bumps [node-mocks-http](https://github.com/howardabrams/node-mocks-http) from 1.7.6 to 1.8.0.
- [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.7.6...v1.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 17:41:59 +00:00
dependabot-preview[bot]
895b4cbed2 Build(deps-dev): bump gatsby-plugin-react-helmet from 3.1.7 to 3.1.8 (#4051)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-react-helmet) from 3.1.7 to 3.1.8.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.1.8/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 17:29:08 +00:00
dependabot-preview[bot]
654ffdb064 Build(deps-dev): bump start-server-and-test from 1.10.0 to 1.10.2 (#4046)
Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.10.0 to 1.10.2.
- [Release notes](https://github.com/bahmutov/start-server-and-test/releases)
- [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.10.0...v1.10.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 17:09:53 +00:00
dependabot-preview[bot]
0d5e5c22da Build(deps-dev): bump gatsby-plugin-styled-components (#4050)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-styled-components) from 3.1.5 to 3.1.6.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.1.6/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 17:00:43 +00:00
dependabot-preview[bot]
5b1b53e495 Build(deps-dev): bump eslint-plugin-jsdoc from 15.9.1 to 15.9.2 (#4049)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 15.9.1 to 15.9.2.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v15.9.1...v15.9.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 16:47:48 +00:00
dependabot-preview[bot]
2b2d1e5a73 Build(deps-dev): bump @types/chai from 4.2.2 to 4.2.3 (#4047)
Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.2.2 to 4.2.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 16:36:25 +00:00
dependabot-preview[bot]
1547fe16ee Build(deps): bump graphql from 14.5.4 to 14.5.6 (#4045)
Bumps [graphql](https://github.com/graphql/graphql-js) from 14.5.4 to 14.5.6.
- [Release notes](https://github.com/graphql/graphql-js/releases)
- [Commits](https://github.com/graphql/graphql-js/compare/v14.5.4...v14.5.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 16:22:36 +00:00
dependabot-preview[bot]
14dd93b248 Build(deps-dev): bump react-error-overlay from 6.0.1 to 6.0.2 (#4044)
Bumps [react-error-overlay](https://github.com/facebook/create-react-app/tree/HEAD/packages/react-error-overlay) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/facebook/create-react-app/releases)
- [Changelog](https://github.com/facebook/create-react-app/blob/master/CHANGELOG-1.x.md)
- [Commits](https://github.com/facebook/create-react-app/commits/react-error-overlay@6.0.2/packages/react-error-overlay)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 16:06:43 +00:00
dependabot-preview[bot]
d4e9b1839d Build(deps-dev): bump gatsby-plugin-remove-trailing-slashes (#4042)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-remove-trailing-slashes) from 2.1.6 to 2.1.7.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.1.7/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-20 15:18:23 +00:00
Pierre-Yves B
a3786ce327 Add Twitch and Wheelmap OAuth app owners (#4039)
* Add Twitch and Wheelmap OAuth app owners

* Update doc/production-hosting.md

Co-Authored-By: Paul Melnikow <github@paulmelnikow.com>
2019-09-18 16:55:59 +00:00
Pierre-Yves B
b73d544a67 Add [MicrobadgerSize] documentation (#4038) 2019-09-17 20:18:49 +01:00
Caleb Cartwright
e6be6bdb30 fix(TwitterFollow): encode usernames for links (#4036) 2019-09-17 00:44:07 +00:00
Caleb Cartwright
233c394fe8 move [MavenMetadata] url to query param (#4021)
* refactor: move MavenMetadata url to query param

* refactor(MavenMetadata): rename query param, update redirect pattern
2019-09-17 00:34:11 +00:00
Caleb Cartwright
b80070985c switch [TeamCity] to pattern and move url to query param (#4022)
* refactor(TeamCity): switch to pattern & move url to query param

* refactor(TeamCity): rename query param
2019-09-16 23:59:04 +00:00
Paul Melnikow
311ccc8834 Fix [CodefactorGrade] again (#4034)
This looks like a case of confusing `Joi.allow()` with `Joi.valid()`.

`Joi.valid(...['A', 'A-']).validate('-')` throws an error but `Joi.allow(...['A', 'A-']).validate('-')` allows it through.

Closes #4033
2019-09-16 17:37:54 +00:00
Paul Melnikow
6560706d01 Finish Typescripterizing the frontend (#4026)
* Typescripterize RequestMarkupButton

* Typescripterize Customizer

* Typescripterize MarkupModalContent (+ tweaks)

* More TypeScript

* More TS

* Fix build

* Remove prop-types dependency

* More types

* Update frontend/components/badge-examples.tsx

* Update frontend/components/badge-examples.tsx

* RequestMarkupButton: Fix weird formatting on click
2019-09-16 14:53:07 +00:00
Caleb Cartwright
69a57fa8dd move [Jira] hostname to query param (#3990)
* refactor: convert Jira host to query param

* tests: fix Jira auth tests

* refactor(Jira): change query param name
2019-09-16 14:38:28 +00:00
Paul Melnikow
437f50d376 Tweak coverage ignores (#4032) 2019-09-16 14:28:02 +00:00
Caleb Cartwright
51d864efc1 move [Discourse] url to query param (#4020)
* refactor: switch Discourse url to query param

* tests: fix e2e test with Discourse example

* refactor(Discourse): change query param name to server

* tests: update e2e test with new discourse param name
2019-09-16 02:15:19 +00:00
Caleb Cartwright
db0ebf1e6a move [Twitter] url to query param (#4027)
* refactor(TwitterUrl): move url to query param

* refactor(Twitter): update suggestion endpoint

* tests: update twitter suggestion int tests

* chore: fix typo in suggestion int test
2019-09-16 02:07:24 +00:00
Caleb Cartwright
d1c0165afd refactor(Website): move url to query param (#4028) 2019-09-16 01:19:55 +00:00
Caleb Cartwright
76b2e2634a fix(GitHubDownloads): type error on latest with pre-downloads (#4030) 2019-09-16 01:08:39 +00:00
Caleb Cartwright
9fe4d739b0 fix [LiberapayGoal] type error when no receiving data exists (#4029)
* fix(LiberapayGoal): type error when no receiving data exists

* chore: prettify things
2019-09-16 00:39:34 +00:00
Paul Melnikow
0434b9b3ba Fix TypeError for invalid [Debian] response (#4023)
Fix #4019
2019-09-15 17:13:21 +00:00
Paul Melnikow
23ac2b0318 Fix AssertionError in [DynamicJson] when a non-object is in the JSON (#4024)
Closes #4018
2019-09-15 17:05:02 +00:00
Paul Melnikow
fe34bcf28b Throw explicit error on invalid [codefactorgrade] color (#4015)
It’s hard to understand how #3813 is persisting. The schema should reject keys not in the object… it’s very puzzling.

This replaces the code used to get the color with a function call that throws an explicit error when the key is missing. It should at least make it clear what the key value is when this fails in the future.
2019-09-14 11:24:57 -05:00
dependabot-preview[bot]
929728a89b Build(deps-dev): bump gatsby from 2.13.62 to 2.15.15 (#4009)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.13.62 to 2.15.15.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.13.62...gatsby@2.15.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 17:33:24 -05:00
dependabot-preview[bot]
e35e2761d7 Build(deps-dev): bump babel-preset-gatsby from 0.2.11 to 0.2.13 (#4003)
Bumps [babel-preset-gatsby](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/babel-preset-gatsby) from 0.2.11 to 0.2.13.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-preset-gatsby/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/babel-preset-gatsby@0.2.13/packages/babel-preset-gatsby)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 17:06:38 -05:00
dependabot-preview[bot]
70568fdc03 Build(deps-dev): bump gatsby-plugin-catch-links from 2.1.7 to 2.1.9 (#3998)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-catch-links) from 2.1.7 to 2.1.9.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.1.9/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 16:50:18 -05:00
dependabot-preview[bot]
7b67eb7660 Build(deps-dev): bump @babel/preset-env from 7.5.5 to 7.6.0 (#3999)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.5.5 to 7.6.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.5.5...v7.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 16:38:27 -05:00
dependabot-preview[bot]
b218c04d93 Build(deps-dev): bump @types/node from 12.7.4 to 12.7.5 (#3997)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 12.7.4 to 12.7.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 15:47:26 -05:00
Honza Hommer
22d713c29b Support custom [Packagist] server (#3986)
* feat(packagist): add custom server query param

* chore(docs): packagist docs tweak

* feat(packagist): custom server downloads badge

* test(packagist): fix custom server tests
2019-09-13 14:38:45 -05:00
dependabot-preview[bot]
4d03e6a028 Build(deps-dev): bump danger from 9.1.8 to 9.2.0 (#4007)
Bumps [danger](https://github.com/danger/danger-js) from 9.1.8 to 9.2.0.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/9.1.8...9.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 19:09:43 +00:00
dependabot-preview[bot]
63e5486e36 Build(deps-dev): bump typescript from 3.6.2 to 3.6.3 (#3995)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.6.2 to 3.6.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v3.6.2...v3.6.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 18:56:44 +00:00
dependabot-preview[bot]
43ea4dcefc Build(deps-dev): bump @types/react-helmet from 5.0.9 to 5.0.10 (#3994)
Bumps [@types/react-helmet](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-helmet) from 5.0.9 to 5.0.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 13:41:58 -05:00
dependabot-preview[bot]
d6cb696681 Build(deps-dev): bump nodemon from 1.19.1 to 1.19.2 (#4006)
Bumps [nodemon](https://github.com/remy/nodemon) from 1.19.1 to 1.19.2.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v1.19.1...v1.19.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 17:56:57 +00:00
dependabot-preview[bot]
f37f121ca8 Build(deps-dev): bump eslint-plugin-mocha from 6.1.0 to 6.1.1 (#4005)
Bumps [eslint-plugin-mocha](https://github.com/lo1tuma/eslint-plugin-mocha) from 6.1.0 to 6.1.1.
- [Release notes](https://github.com/lo1tuma/eslint-plugin-mocha/releases)
- [Changelog](https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lo1tuma/eslint-plugin-mocha/compare/6.1.0...6.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 17:45:44 +00:00
dependabot-preview[bot]
48aa2633ed Build(deps): bump graphql from 14.4.2 to 14.5.4 (#4002)
Bumps [graphql](https://github.com/graphql/graphql-js) from 14.4.2 to 14.5.4.
- [Release notes](https://github.com/graphql/graphql-js/releases)
- [Commits](https://github.com/graphql/graphql-js/compare/v14.4.2...v14.5.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 17:32:06 +00:00
dependabot-preview[bot]
85adb282f8 Build(deps-dev): bump eslint-plugin-sort-class-members (#4004)
Bumps [eslint-plugin-sort-class-members](https://github.com/bryanrsmith/eslint-plugin-sort-class-members) from 1.5.0 to 1.6.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.5.0...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 17:15:23 +00:00
dependabot-preview[bot]
db274ad4c4 Build(deps-dev): bump eslint-config-prettier from 6.2.0 to 6.3.0 (#4000)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v6.2.0...v6.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 16:57:53 +00:00
dependabot-preview[bot]
98ddb26210 Build(deps-dev): bump gatsby-plugin-remove-trailing-slashes (#4001)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-remove-trailing-slashes) from 2.1.2 to 2.1.6.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.1.6/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 16:35:14 +00:00
dependabot-preview[bot]
60e09f3d03 Build(deps-dev): bump eslint-plugin-node from 9.2.0 to 10.0.0 (#3993)
Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 9.2.0 to 10.0.0.
- [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases)
- [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v9.2.0...v10.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 16:18:25 +00:00
dependabot-preview[bot]
10f92b7d2a Build(deps): bump simple-icons from 1.14.0 to 1.15.0 (#3996)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/compare/1.14.0...1.15.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 16:05:06 +00:00
dependabot-preview[bot]
fc52c139e5 Build(deps-dev): bump nock from 11.3.2 to 11.3.4 (#3992)
Bumps [nock](https://github.com/nock/nock) from 11.3.2 to 11.3.4.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/compare/v11.3.2...v11.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 15:52:33 +00:00
dependabot-preview[bot]
4f8ab9c4bb Build(deps): bump path-to-regexp from 3.0.0 to 3.1.0 (#3971)
Bumps [path-to-regexp](https://github.com/pillarjs/path-to-regexp) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/pillarjs/path-to-regexp/releases)
- [Changelog](https://github.com/pillarjs/path-to-regexp/blob/master/History.md)
- [Commits](https://github.com/pillarjs/path-to-regexp/compare/v3.0.0...v3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 15:42:12 +00:00
dependabot-preview[bot]
ff99653e6f Build(deps-dev): bump gatsby-plugin-react-helmet from 3.1.3 to 3.1.7 (#3991)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-react-helmet) from 3.1.3 to 3.1.7.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.1.7/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-13 14:43:29 +00:00
Sandro Rodrigues
fa0a25cf0a Added [SecurityHeaders] badge (#3958)
* Added security headers service.

* Small improvements from provided feedback.

* Fixed failing tests.

* Removed grade condition on render method.

* Changed protocol and path from pattern to querystring
2019-09-10 20:54:49 -05:00
Pierre-Yves B
e755e61203 Add Twitch keys to configuration files (#3985) 2019-09-10 21:28:47 +01:00
dependabot-preview[bot]
4848c7b327 Build(deps-dev): bump gatsby-plugin-typescript from 2.1.6 to 2.1.7 (#3977)
Bumps [gatsby-plugin-typescript](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-typescript) from 2.1.6 to 2.1.7.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-typescript/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-typescript@2.1.7/packages/gatsby-plugin-typescript)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-10 11:01:47 -05:00
dependabot-preview[bot]
c34a0e768b Build(deps-dev): bump gatsby-plugin-page-creator from 2.1.15 to 2.1.17 (#3978)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-page-creator) from 2.1.15 to 2.1.17.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.1.17/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-10 03:17:10 +00:00
dependabot-preview[bot]
9feae8fef6 Build(deps-dev): bump gatsby-plugin-styled-components (#3975)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-styled-components) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.1.5/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-10 03:07:46 +00:00
Andy Li
4b9053d2d5 add [twitch] user status badge (#3683)
* add /twitch/status/:user badge

* update comments

* use a proper schema for the Twitch API calls

* use a token to make Twitch api calls

* fix handling of rate-limit error and bad token error

* [twitch] get a token as soon as creating a Twitch service

* [twitch] start both requests to users and stream before awaiting

* [twitch] set a timeout to replace the token before it expires

* [twitch] use authHelper

* [twitch] skip tests when no credentials

* [twitch] add one more status test

* twitch: do not check whether a user exists
2019-09-09 16:41:32 -05:00
dependabot-preview[bot]
5d005e40e6 Build(deps-dev): bump @types/chai from 4.2.1 to 4.2.2 (#3979)
Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.2.1 to 4.2.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 20:47:52 +00:00
chris48s
60bd7a69a7 link to contributing.shields.io in the docs (#3957)
* link to shields-docs.netlify.com in the docs

* update links to contributing.shields.io
2019-09-09 20:37:43 +00:00
dependabot-preview[bot]
596e308d64 Build(deps-dev): bump @babel/polyfill from 7.4.4 to 7.6.0 (#3974)
Bumps [@babel/polyfill](https://github.com/babel/babel) from 7.4.4 to 7.6.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.4...v7.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 20:30:27 +00:00
dependabot-preview[bot]
b86ea56bd5 Build(deps-dev): bump @babel/core from 7.5.5 to 7.6.0 (#3973)
Bumps [@babel/core](https://github.com/babel/babel) from 7.5.5 to 7.6.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.5.5...v7.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 20:19:14 +00:00
dependabot-preview[bot]
0b77d7cf86 Build(deps-dev): bump eslint-config-prettier from 6.0.0 to 6.2.0 (#3980)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 6.0.0 to 6.2.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v6.0.0...v6.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 19:30:21 +00:00
dependabot-preview[bot]
13e39a246a Build(deps): bump cross-env from 5.2.0 to 5.2.1 (#3976)
Bumps [cross-env](https://github.com/kentcdodds/cross-env) from 5.2.0 to 5.2.1.
- [Release notes](https://github.com/kentcdodds/cross-env/releases)
- [Changelog](https://github.com/kentcdodds/cross-env/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kentcdodds/cross-env/compare/v5.2.0...v5.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 19:05:34 +00:00
dependabot-preview[bot]
3fb51af197 Build(deps-dev): bump typescript from 3.5.3 to 3.6.2 (#3967)
* Build(deps-dev): bump typescript from 3.5.3 to 3.6.2

Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.5.3 to 3.6.2.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v3.5.3...v3.6.2)

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

* Add types/node and pin it

ref https://github.com/microsoft/TypeScript/issues/32333
2019-09-09 15:54:29 +00:00
dependabot-preview[bot]
a0d6728d88 Build(deps-dev): bump @babel/register from 7.5.5 to 7.6.0 (#3968)
Bumps [@babel/register](https://github.com/babel/babel) from 7.5.5 to 7.6.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.5.5...v7.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 15:41:38 +00:00
dependabot-preview[bot]
d4503d60b3 Build(deps-dev): bump gatsby-plugin-styled-components (#3965)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-styled-components) from 3.1.2 to 3.1.4.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.1.4/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 15:30:02 +00:00
dependabot-preview[bot]
f8199931ae Build(deps-dev): bump sinon from 7.4.1 to 7.4.2 (#3966)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.4.1 to 7.4.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v7.4.1...v7.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 15:09:26 +00:00
dependabot-preview[bot]
087f197cc1 Build(deps-dev): bump eslint-plugin-standard from 4.0.0 to 4.0.1 (#3972)
Bumps [eslint-plugin-standard](https://github.com/standard/eslint-plugin-standard) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/standard/eslint-plugin-standard/releases)
- [Commits](https://github.com/standard/eslint-plugin-standard/compare/v4.0.0...v4.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 14:55:29 +00:00
dependabot-preview[bot]
24f3be7fce Build(deps-dev): bump portfinder from 1.0.23 to 1.0.24 (#3969)
Bumps [portfinder](https://github.com/indexzero/node-portfinder) from 1.0.23 to 1.0.24.
- [Release notes](https://github.com/indexzero/node-portfinder/releases)
- [Commits](https://github.com/indexzero/node-portfinder/compare/v1.0.23...v1.0.24)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 14:42:26 +00:00
dependabot-preview[bot]
a8140ce010 Build(deps-dev): bump @types/chai from 4.2.0 to 4.2.1 (#3964)
Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 14:12:57 +00:00
dependabot-preview[bot]
5cb53fc8b3 Build(deps-dev): bump husky from 3.0.4 to 3.0.5 (#3963)
Bumps [husky](https://github.com/typicode/husky) from 3.0.4 to 3.0.5.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v3.0.4...v3.0.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-09 09:02:59 -05:00
Pierre-Yves B
c6d52e40b8 Fix [Scrutinizer] error when using default branch without analysis data (#3962) 2019-09-08 21:09:00 +00:00
chris48s
a75b9b3c8c document exceptions (#3961) 2019-09-08 20:58:45 +00:00
chris48s
b3be4d94d5 require key 'latest' to exist (#3956) 2019-09-07 20:03:41 +00:00
chris48s
873172522f [dynamicxml] wrap xpath errors (#3955)
Closes #3796
2019-09-07 13:02:27 -04:00
Anand Chowdhary
58a5239e18 Add [Netlify] (fixed #3129) (#3953)
* Add Netlify (fixed #3129)

* Update services/netlify/netlify.service.js

Co-Authored-By: ExE Boss <3889017+ExE-Boss@users.noreply.github.com>

* Remove pattern from return statement

Co-Authored-By: ExE Boss <3889017+ExE-Boss@users.noreply.github.com>

* Add Netlify namedLogo to return statement

Co-Authored-By: ExE Boss <3889017+ExE-Boss@users.noreply.github.com>

* Change label from "build" to "netlify" in test

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Change label from "build" to "netlify" in test

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* test(netlify): Fix failing tests

Co-Authored-By: ExE Boss <3889017+ExE-Boss@users.noreply.github.com>

* Fix "netlify" spelling in label

Co-Authored-By: ExE Boss <3889017+ExE-Boss@users.noreply.github.com>

* Use const instead of let for result

Co-Authored-By: ExE Boss <3889017+ExE-Boss@users.noreply.github.com>

* Change "project not found" to "not found"

* Use unknown as fallback response

Co-Authored-By: ExE Boss <3889017+ExE-Boss@users.noreply.github.com>

* Add documentation for project ID, remove commented part

* Fix documentation key in example
2019-09-06 12:21:17 -05:00
Paul Melnikow
926e837457 Exclude more in-use GitHub IPs from rate limiting and add metrics (#3950)
Fix issue where badges loaded through GitHub intermittently generated 502's on camo.

Ref https://github.com/badges/shields/issues/3874#issuecomment-527904731
2019-09-04 11:30:32 -04:00
dependabot-preview[bot]
a052d485fa Build(deps-dev): bump eslint-config-standard-react from 8.0.0 to 9.0.0 (#3906)
* Build(deps-dev): bump eslint-config-standard-react from 8.0.0 to 9.0.0

Bumps [eslint-config-standard-react](https://github.com/feross/eslint-config-standard-react) from 8.0.0 to 9.0.0.
- [Release notes](https://github.com/feross/eslint-config-standard-react/releases)
- [Commits](https://github.com/feross/eslint-config-standard-react/compare/v8.0.0...v9.0.0)

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

* Add prettier/react to ignore react/jsx-indent
2019-09-04 00:54:18 +00:00
dependabot-preview[bot]
0cdf1d376e Build(deps-dev): bump eslint-config-standard-jsx from 6.0.2 to 8.1.0 (#3943)
* Build(deps-dev): bump eslint-config-standard-jsx from 6.0.2 to 8.1.0

Bumps [eslint-config-standard-jsx](https://github.com/standard/eslint-config-standard-jsx) from 6.0.2 to 8.1.0.
- [Release notes](https://github.com/standard/eslint-config-standard-jsx/releases)
- [Commits](https://github.com/standard/eslint-config-standard-jsx/compare/v6.0.2...v8.1.0)

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

* Clean lint; add rel="noopener noreferrer"

Ref https://mathiasbynens.github.io/rel-noopener
2019-09-04 00:34:44 +00:00
Paul Melnikow
7a80bab640 Bump npm from 6.10.3 to 6.11.3 (#3949)
[npm 6.11.3 has been released](https://npm.community/t/release-6-11-3/9873/1) which fixes [the regression we've been seeing](https://npm.community/t/6-11-1-some-dependencies-are-no-longer-being-installed/9586/4).

Ref #3904
2019-09-03 23:24:24 +00:00
Paul Melnikow
b7a29f20ef Add a response-time metric (#3948)
* Refactor existing metrics support into MetricHelper

This completes the refactor done at https://github.com/badges/shields/pull/3662#issuecomment-509011229 in anticipation of adding more metrics support, such as response size of an upstream service, or response time.

* Clean up

* Renames

* Add response time metrics

This adds around 30 new metrics to cover response times at a fairly granular level. We may be able to shrink the number of buckets with time, though I think using 30 metrics is probably okay given that I think may become our most important metric.

* Fix
2019-09-03 22:19:24 +00:00
Paul Melnikow
33389e352d Tweak Gitpod config (#3934)
This disables the comments like https://github.com/badges/shields/pull/3933#issuecomment-526905743 which seem a bit chatty, as the review apps can be accessed from the checks.

This and also turns off builds for branches. For the most part we keep PRs open when branches are at a stage of being ready for useful review, so I think that should be sufficient for us.
2019-09-03 17:12:38 +00:00
Pierre-Yves B
4190609d1b Handle missing Symfony Insight grade gracefully (#3933) 2019-09-03 09:49:00 +01:00
Réda Housni Alaoui
94fdb81d1c Maven central service should not parse versions as number (#3935) 2019-09-02 12:47:18 -05:00
dependabot-preview[bot]
0f687540d3 Build(deps-dev): bump gatsby-plugin-typescript from 2.1.2 to 2.1.6 (#3944)
Bumps [gatsby-plugin-typescript](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-typescript) from 2.1.2 to 2.1.6.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-typescript/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-typescript@2.1.6/packages/gatsby-plugin-typescript)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 11:37:24 -05:00
dependabot-preview[bot]
9fec1dce2a Build(deps-dev): bump gatsby-plugin-catch-links from 2.1.3 to 2.1.7 (#3942)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-catch-links) from 2.1.3 to 2.1.7.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.1.7/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 11:26:30 -05:00
dependabot-preview[bot]
b198ccb773 Build(deps): bump query-string from 6.8.2 to 6.8.3 (#3941)
Bumps [query-string](https://github.com/sindresorhus/query-string) from 6.8.2 to 6.8.3.
- [Release notes](https://github.com/sindresorhus/query-string/releases)
- [Commits](https://github.com/sindresorhus/query-string/compare/v6.8.2...v6.8.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 11:13:34 -05:00
dependabot-preview[bot]
46e6a35ea3 Build(deps-dev): bump eslint-plugin-react-hooks from 1.7.0 to 2.0.1 (#3940)
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 1.7.0 to 2.0.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 10:38:28 -05:00
dependabot-preview[bot]
3672ba2d54 Build(deps-dev): bump gatsby-plugin-page-creator from 2.1.5 to 2.1.15 (#3939)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-page-creator) from 2.1.5 to 2.1.15.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.1.15/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 10:26:02 -05:00
dependabot-preview[bot]
f9398e6373 Build(deps-dev): bump eslint-plugin-node from 9.1.0 to 9.2.0 (#3938)
Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 9.1.0 to 9.2.0.
- [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases)
- [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v9.1.0...v9.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 10:09:05 -05:00
dependabot-preview[bot]
7f74337f5b Build(deps-dev): bump lint-staged from 9.2.3 to 9.2.5 (#3937)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 9.2.3 to 9.2.5.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v9.2.3...v9.2.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 09:50:19 -05:00
dependabot-preview[bot]
da03819de3 Build(deps-dev): bump eslint-plugin-jsdoc from 15.8.3 to 15.9.1 (#3936)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 15.8.3 to 15.9.1.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v15.8.3...v15.9.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-02 09:37:21 -05:00
Jan Keromnes
2f8704f0dc Improve Gitpod automated setup (#3880)
* Gitpod is no longer in Beta

* Automatically open the web preview on start-up in Gitpod

* Accelerate Gitpod start-up with continuously prebuilt workspaces

* Install Prettier VS Code extension in Gitpod
2019-08-29 18:17:03 +00:00
dependabot-preview[bot]
d2782ef466 Build(deps): bump simple-icons from 1.13.0 to 1.14.0 (#3921)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.13.0 to 1.14.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits/1.14.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-27 19:55:07 -05:00
dependabot-preview[bot]
0f5d5e53ec Build(deps): bump @sentry/node from 5.6.1 to 5.6.2 (#3920)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 5.6.1 to 5.6.2.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/5.6.1...5.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-27 19:36:47 -05:00
dependabot-preview[bot]
1087c96d78 Build(deps-dev): bump nock from 11.0.0 to 11.3.2 (#3919)
Bumps [nock](https://github.com/nock/nock) from 11.0.0 to 11.3.2.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/next/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-27 19:19:01 -05:00
chris48s
136c1f3525 more lenient semver coerce in [wordpress] version (#3914) 2019-08-27 21:09:37 +01:00
Paul Melnikow
51f04ff9d1 Upgrade ioredis from 4.13.1 to 4.14.1 (#3925)
The bug has been fixed: https://github.com/luin/ioredis/pull/949

Have tested this locally using `REDIS_URL=... node scripts/redis-connectivity-test.js`.
2019-08-27 09:51:34 -04:00
Paul Melnikow
433c73a49f Add some implementation comments to Luarocks (#3924)
These came from https://github.com/badges/shields/pull/3094#issuecomment-467396574
2019-08-27 08:41:26 -04:00
dependabot-preview[bot]
7d77a75da1 Build(deps-dev): bump eslint-plugin-mocha from 6.0.0 to 6.1.0 (#3918)
Bumps [eslint-plugin-mocha](https://github.com/lo1tuma/eslint-plugin-mocha) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/lo1tuma/eslint-plugin-mocha/releases)
- [Changelog](https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lo1tuma/eslint-plugin-mocha/compare/6.0.0...6.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-26 18:56:56 -05:00
dependabot-preview[bot]
82474328cb Build(deps-dev): bump eslint-plugin-jsdoc from 15.8.1 to 15.8.3 (#3917)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 15.8.1 to 15.8.3.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v15.8.1...v15.8.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-26 18:13:42 -05:00
dependabot-preview[bot]
a1ca58e8a0 Build(deps-dev): bump babel-preset-gatsby from 0.2.8 to 0.2.11 (#3916)
Bumps [babel-preset-gatsby](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/babel-preset-gatsby) from 0.2.8 to 0.2.11.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-preset-gatsby/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/babel-preset-gatsby@0.2.11/packages/babel-preset-gatsby)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-26 17:18:55 -05:00
dependabot-preview[bot]
8a1b96bb30 Build(deps-dev): bump portfinder from 1.0.22 to 1.0.23 (#3905)
Bumps [portfinder](https://github.com/indexzero/node-portfinder) from 1.0.22 to 1.0.23.
- [Release notes](https://github.com/indexzero/node-portfinder/releases)
- [Commits](https://github.com/indexzero/node-portfinder/compare/v1.0.22...v1.0.23)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-26 16:48:41 -05:00
dependabot-preview[bot]
04f13e9846 Build(deps-dev): bump react-modal from 3.9.1 to 3.10.1 (#3915)
Bumps [react-modal](https://github.com/reactjs/react-modal) from 3.9.1 to 3.10.1.
- [Release notes](https://github.com/reactjs/react-modal/releases)
- [Changelog](https://github.com/reactjs/react-modal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-modal/compare/v3.9.1...v3.10.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-26 16:29:50 -05:00
dependabot[bot]
bb06ffa063 Build(deps): bump eslint-utils from 1.3.1 to 1.4.2 (#3923)
Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.3.1...v1.4.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-26 15:37:11 -04:00
Pierre-Yves B
e00af3200c Handle more [Twitter] invalid user inputs (#3922) 2019-08-26 17:38:36 +01:00
Caleb Cartwright
c9cd77a746 chore: update JenkinsTests example (#3912) 2019-08-25 14:01:02 -05:00
Paul Melnikow
fb186e2cf5 Typescripterize QueryStringBuilder and PathBuilder (#3885) 2019-08-25 14:46:37 -04:00
chris48s
dd89b19266 add missing alt text to some <img> tags (#3903) 2019-08-25 07:27:10 -04:00
Patrick Faion
9c5ecc2c2d Add service for [GitHubLabels] (#3902)
* Add service for github labels

* Set better category

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Add more restrictive schema for color property

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Make error message more consistent
2019-08-24 17:01:32 -05:00
Caleb Cartwright
449e3d1f84 fix package-lock.json to restore heroku deploys (#3904)
* chore: fix package-lock.json

* chore: another package-lock fix attempt

* chore: another fix attempt

* chore: another fix attempt

* chore: ?

* chore: 21st times the charm

* chore: more attempts....

* chore: at a loss

* chore: rollback some unneeded fix attempts

* chore: move gh-badges install hack to postinstall

* chore: disable cypress and husky setup in heroku

* Apply suggestions from code review

Co-Authored-By: Paul Melnikow <github@paulmelnikow.com>

* chore: update node engines and remove ghbadges

* Check versions

* Pin to working npm version

* Reset unrelated changes

* Reset one more file
2019-08-24 15:29:08 -05:00
Caleb Cartwright
a0be4aae1c tests: update DubDownload service test for reliability (#3910) 2019-08-24 12:33:27 -05:00
Caleb Cartwright
997cb0953c tests: improve durability of nexus service test (#3911) 2019-08-24 12:25:11 -05:00
Caleb Cartwright
fad4d1e286 tests: improve reliability of Snyk tests (#3900) 2019-08-21 08:18:36 -05:00
Paul Melnikow
35ef9be434 Typescripterize BadgeExamples and SuggestionAndSearch (#3879)
The two different kinds of data that can be passed to `<BadgeExample />` were a bit less similar than I thought, so this includes a little refactor related to that which isn't perfect, but leaves things in a cleaner place than before.
2019-08-21 08:25:03 +01:00
Paul Melnikow
af81095794 Fix TLS errors preventing Redis connections in production (#3899)
ioredis 4.14.0 introduced an issue where custom TLS options are no longer honored. I reported it here: luin/ioredis#947

This has been preventing the server from using GitHub tokens, however I'm not sure whether or not this has been causing noticeable issues.

For now let's downgrade to the latest working version, which I've confirmed working via the script (checked in).
2019-08-20 19:03:51 +01:00
dependabot-preview[bot]
316749bd69 Build(deps-dev): bump danger from 9.1.5 to 9.1.8 (#3897)
Bumps [danger](https://github.com/danger/danger-js) from 9.1.5 to 9.1.8.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/9.1.5...9.1.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 17:01:32 -05:00
dependabot-preview[bot]
6d171018ae Build(deps-dev): bump husky from 2.4.1 to 3.0.4 (#3896)
Bumps [husky](https://github.com/typicode/husky) from 2.4.1 to 3.0.4.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v2.4.1...v3.0.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 16:51:06 -05:00
dependabot-preview[bot]
39f8135d45 Build(deps): bump @hapi/joi from 15.1.0 to 15.1.1 (#3894)
Bumps [@hapi/joi](https://github.com/hapijs/joi) from 15.1.0 to 15.1.1.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hapijs/joi/compare/v15.1.0...v15.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 16:31:06 -05:00
dependabot-preview[bot]
519dec29c7 Build(deps-dev): bump concurrently from 4.1.1 to 4.1.2 (#3891)
Bumps [concurrently](https://github.com/kimmobrunfeldt/concurrently) from 4.1.1 to 4.1.2.
- [Release notes](https://github.com/kimmobrunfeldt/concurrently/releases)
- [Commits](https://github.com/kimmobrunfeldt/concurrently/compare/v4.1.1...v4.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 13:58:20 -05:00
dependabot-preview[bot]
75525f3aef Build(deps-dev): bump eslint-plugin-jsdoc from 15.8.0 to 15.8.1 (#3887)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 15.8.0 to 15.8.1.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v15.8.0...v15.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 13:17:27 -05:00
dependabot-preview[bot]
92ff5bb8bd Build(deps): bump dotenv from 8.0.0 to 8.1.0 (#3886)
Bumps [dotenv](https://github.com/motdotla/dotenv) from 8.0.0 to 8.1.0.
- [Release notes](https://github.com/motdotla/dotenv/releases)
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/motdotla/dotenv/compare/v8.0.0...v8.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 11:40:20 -05:00
dependabot-preview[bot]
1eb18e0102 Build(deps-dev): bump lint-staged from 9.2.1 to 9.2.3 (#3890)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 9.2.1 to 9.2.3.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v9.2.1...v9.2.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 10:44:09 -05:00
dependabot-preview[bot]
02075287f2 Build(deps): bump fast-xml-parser from 3.12.19 to 3.12.20 (#3888)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.19 to 3.12.20.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 10:18:31 -05:00
Caleb Cartwright
08474aed11 move [Nexus] server and queryOpt from route to query params (#3792)
* refactor(Nexus): move server and queryOpt from route to query params

* tests: fix nexus auth test

* chore: satiate prettier
2019-08-19 09:45:02 -05:00
dependabot-preview[bot]
fa4068c96c Build(deps-dev): bump rimraf from 2.7.0 to 3.0.0 (#3893)
Bumps [rimraf](https://github.com/isaacs/rimraf) from 2.7.0 to 3.0.0.
- [Release notes](https://github.com/isaacs/rimraf/releases)
- [Commits](https://github.com/isaacs/rimraf/compare/v2.7.0...v3.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 15:26:44 +01:00
dependabot-preview[bot]
8e1a81b62d Build(deps-dev): bump @types/chai-enzyme from 0.6.6 to 0.6.7 (#3889)
Bumps [@types/chai-enzyme](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai-enzyme) from 0.6.6 to 0.6.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai-enzyme)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 14:27:45 +01:00
dependabot-preview[bot]
6538aeefc0 Build(deps-dev): bump portfinder from 1.0.21 to 1.0.22 (#3892)
Bumps [portfinder](https://github.com/indexzero/node-portfinder) from 1.0.21 to 1.0.22.
- [Release notes](https://github.com/indexzero/node-portfinder/releases)
- [Commits](https://github.com/indexzero/node-portfinder/compare/v1.0.21...v1.0.22)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-19 13:56:47 +01:00
chris48s
20202b5bfa convert eslint-jsdoc warnings to errors (#3882)
* convert eslint-jsdoc warnings to errors
* appease linter
2019-08-18 20:05:18 +01:00
chris48s
5168675d0d move [githubtag] and [githubrelease] under /v, move variants to query params (#3610)
* move GH tag and release under /v, move variants to query params
    - move github /tag and /release under /v
    - both sort by date as default
    - specify sort=date/semver, include_prereleases as query params
    - use graphql api for tags

* pass string params from example defs to modal
2019-08-17 22:16:41 +01:00
Caleb Cartwright
b14203e0dd tests: fix OSSLifecycle service test with new active target (#3877) 2019-08-16 11:34:32 -05:00
Paul Melnikow
583cc22471 Typescripterize StaticBadgeMaker (#3876) 2019-08-16 19:20:42 +03:00
Paul Melnikow
b36d01ba50 More TypeScript in the frontend (#3742) 2019-08-16 18:29:05 +03:00
chris48s
02e1baf690 improve docs for base service classes (#3850)
improve docs for base service classes
2019-08-14 21:54:46 +01:00
dependabot-preview[bot]
adcf2ff3c1 Build(deps-dev): bump gatsby from 2.13.61 to 2.13.62 (#3872)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.13.61 to 2.13.62.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.13.61...gatsby@2.13.62)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 21:28:34 -05:00
dependabot-preview[bot]
80d08d8e0a Build(deps-dev): bump gatsby-plugin-catch-links from 2.1.2 to 2.1.3 (#3871)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-catch-links) from 2.1.2 to 2.1.3.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.1.3/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 21:19:03 -05:00
dependabot-preview[bot]
38b0afd6f9 Build(deps-dev): bump rimraf from 2.6.3 to 2.7.0 (#3870)
Bumps [rimraf](https://github.com/isaacs/rimraf) from 2.6.3 to 2.7.0.
- [Release notes](https://github.com/isaacs/rimraf/releases)
- [Commits](https://github.com/isaacs/rimraf/compare/v2.6.3...v2.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 21:07:13 -05:00
dependabot-preview[bot]
e5c677e8b8 Build(deps): bump fast-xml-parser from 3.12.16 to 3.12.19 (#3869)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 3.12.16 to 3.12.19.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 20:58:07 -05:00
dependabot-preview[bot]
ffdff9fde6 Build(deps-dev): bump @babel/core from 7.4.5 to 7.5.5 (#3868)
Bumps [@babel/core](https://github.com/babel/babel) from 7.4.5 to 7.5.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.5...v7.5.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 20:47:58 -05:00
dependabot-preview[bot]
6f1b919c41 Build(deps): bump @sentry/node from 5.5.0 to 5.6.1 (#3867)
Bumps [@sentry/node](https://github.com/getsentry/sentry-javascript) from 5.5.0 to 5.6.1.
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/5.5.0...5.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 20:39:16 -05:00
dependabot-preview[bot]
c4da72e996 Build(deps-dev): bump @types/react-helmet from 5.0.8 to 5.0.9 (#3866)
Bumps [@types/react-helmet](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-helmet) from 5.0.8 to 5.0.9.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 20:11:36 -05:00
dependabot-preview[bot]
174fabf079 Build(deps-dev): bump @types/chai from 4.1.7 to 4.2.0 (#3865)
Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.1.7 to 4.2.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 19:48:05 -05:00
dependabot-preview[bot]
86e76c0050 Build(deps-dev): bump danger from 9.0.3 to 9.1.5 (#3864)
Bumps [danger](https://github.com/danger/danger-js) from 9.0.3 to 9.1.5.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/9.0.3...9.1.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 19:32:12 -05:00
dependabot-preview[bot]
93246f909e Build(deps-dev): bump babel-plugin-istanbul from 5.1.4 to 5.2.0 (#3862)
Bumps [babel-plugin-istanbul](https://github.com/istanbuljs/babel-plugin-istanbul) from 5.1.4 to 5.2.0.
- [Release notes](https://github.com/istanbuljs/babel-plugin-istanbul/releases)
- [Changelog](https://github.com/istanbuljs/babel-plugin-istanbul/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/babel-plugin-istanbul/compare/v5.1.4...v5.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 19:19:57 -05:00
dependabot-preview[bot]
b7bf949126 Build(deps): bump simple-icons from 1.11.0 to 1.13.0 (#3863)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.11.0 to 1.13.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 18:59:28 -05:00
dependabot-preview[bot]
10e37b77e5 Build(deps-dev): bump lint-staged from 8.1.7 to 9.2.1 (#3861)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 8.1.7 to 9.2.1.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v8.1.7...v9.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 18:33:36 -05:00
dependabot-preview[bot]
b73190d1e0 Build(deps-dev): bump eslint-plugin-cypress from 2.6.0 to 2.6.1 (#3860)
Bumps [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/cypress-io/eslint-plugin-cypress/releases)
- [Commits](https://github.com/cypress-io/eslint-plugin-cypress/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 17:57:21 -05:00
dependabot-preview[bot]
4198c0504c Build(deps-dev): bump start-server-and-test from 1.9.1 to 1.10.0 (#3854)
Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.9.1 to 1.10.0.
- [Release notes](https://github.com/bahmutov/start-server-and-test/releases)
- [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.9.1...v1.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 17:42:54 -05:00
dependabot-preview[bot]
42bd89c331 Build(deps-dev): bump gatsby from 2.13.51 to 2.13.61 (#3856)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.13.51 to 2.13.61.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.13.51...gatsby@2.13.61)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 17:28:53 -05:00
dependabot-preview[bot]
ee8dc3ba01 Build(deps-dev): bump nock from 11.0.0-beta.30 to 11.0.0 (#3858)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.30 to 11.0.0.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/next/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 17:14:46 -05:00
dependabot-preview[bot]
03ce8aaece Build(deps-dev): bump react-error-overlay from 5.1.6 to 6.0.1 (#3857)
Bumps [react-error-overlay](https://github.com/facebook/create-react-app/tree/HEAD/packages/react-error-overlay) from 5.1.6 to 6.0.1.
- [Release notes](https://github.com/facebook/create-react-app/releases)
- [Changelog](https://github.com/facebook/create-react-app/blob/master/CHANGELOG-1.x.md)
- [Commits](https://github.com/facebook/create-react-app/commits/react-error-overlay@6.0.1/packages/react-error-overlay)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 16:59:43 -05:00
dependabot-preview[bot]
e56a14be8a Build(deps-dev): bump react-dom from 16.8.6 to 16.9.0 (#3855)
Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.8.6 to 16.9.0.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.9.0/packages/react-dom)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 16:50:05 -05:00
dependabot-preview[bot]
2b3a77646a Build(deps): bump pretty-bytes from 5.2.0 to 5.3.0 (#3859)
Bumps [pretty-bytes](https://github.com/sindresorhus/pretty-bytes) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/sindresorhus/pretty-bytes/releases)
- [Commits](https://github.com/sindresorhus/pretty-bytes/compare/v5.2.0...v5.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 21:48:43 +01:00
dependabot-preview[bot]
137e9d27be Build(deps): [security] bump lodash from 4.17.11 to 4.17.15 (#3853)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.15. **This update includes a security fix.**
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.15)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 21:16:50 +01:00
dependabot-preview[bot]
77cb8a87ea Build(deps): bump ioredis from 4.11.1 to 4.14.0 (#3844)
Bumps [ioredis](https://github.com/luin/ioredis) from 4.11.1 to 4.14.0.
- [Release notes](https://github.com/luin/ioredis/releases)
- [Changelog](https://github.com/luin/ioredis/blob/master/Changelog.md)
- [Commits](https://github.com/luin/ioredis/compare/v4.11.1...v4.14.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-13 08:52:27 -05:00
dependabot-preview[bot]
e03287bfca Build(deps-dev): bump react from 16.8.6 to 16.9.0 (#3847)
Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.8.6 to 16.9.0.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v16.9.0/packages/react)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-12 18:36:20 -05:00
dependabot-preview[bot]
5eea99aee5 Build(deps-dev): bump gatsby-plugin-remove-trailing-slashes (#3842)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-remove-trailing-slashes) from 2.1.0 to 2.1.2.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.1.2/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-12 18:19:22 -05:00
dependabot-preview[bot]
5272d230bb Build(deps-dev): bump walkdir from 0.4.0 to 0.4.1 (#3848)
Bumps [walkdir](https://github.com/soldair/node-walkdir) from 0.4.0 to 0.4.1.
- [Release notes](https://github.com/soldair/node-walkdir/releases)
- [Changelog](https://github.com/soldair/node-walkdir/blob/master/CHANGELOG.md)
- [Commits](https://github.com/soldair/node-walkdir/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-12 17:57:29 -05:00
dependabot-preview[bot]
02e625edf9 Build(deps-dev): bump clipboard-copy from 3.0.0 to 3.1.0 (#3841)
Bumps [clipboard-copy](https://github.com/feross/clipboard-copy) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/feross/clipboard-copy/releases)
- [Commits](https://github.com/feross/clipboard-copy/compare/v3.0.0...v3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-12 22:08:29 +01:00
dependabot-preview[bot]
a3f81f94d9 Build(deps-dev): bump cypress from 3.4.0 to 3.4.1 (#3846)
Bumps [cypress](https://github.com/cypress-io/cypress) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Commits](https://github.com/cypress-io/cypress/compare/v3.4.0...v3.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-12 21:55:41 +01:00
dependabot-preview[bot]
e190b1ba36 Build(deps-dev): bump eslint-plugin-react-hooks from 1.6.1 to 1.7.0 (#3843)
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 1.6.1 to 1.7.0.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-12 21:47:31 +01:00
dependabot-preview[bot]
a1e76ee88f Build(deps-dev): bump eslint-plugin-mocha from 5.3.0 to 6.0.0 (#3840)
Bumps [eslint-plugin-mocha](https://github.com/lo1tuma/eslint-plugin-mocha) from 5.3.0 to 6.0.0.
- [Release notes](https://github.com/lo1tuma/eslint-plugin-mocha/releases)
- [Changelog](https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/lo1tuma/eslint-plugin-mocha/compare/5.3.0...6.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-12 21:29:16 +01:00
Caleb Cartwright
452b9840ea tests: fix aur vote service test (#3837) 2019-08-12 06:20:12 -05:00
Caleb Cartwright
750c8fda62 chore: add jsdoc to osslifecycle function (#3838) 2019-08-11 21:49:13 +03:00
Caleb Cartwright
a0fb2aab43 chore: fix sinon in lockfile (#3835) 2019-08-10 23:00:41 +03:00
Caleb Cartwright
fb2727d22e tests: make MozillaObservatory service tests more durable (#3817) 2019-08-09 15:56:53 -05:00
dependabot-preview[bot]
4b5568cb9e Build(deps-dev): bump eslint-plugin-jsdoc from 10.0.3 to 15.8.0 (#3828)
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 10.0.3 to 15.8.0.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v10.0.3...v15.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-06 22:16:58 +01:00
Paul Melnikow
4eb6d25ff7 Fix trailing 0 in [F-Droid] yaml format (#3831)
Closes #3830
2019-08-06 15:39:55 +02:00
Caleb Cartwright
acfcf82d1f fix: tweak build schema for AzureDevOps to handle never built use case (#3829) 2019-08-06 08:09:58 -05:00
dependabot-preview[bot]
9f0acd8e80 Build(deps): bump query-string from 6.7.0 to 6.8.2 (#3823)
Bumps [query-string](https://github.com/sindresorhus/query-string) from 6.7.0 to 6.8.2.
- [Release notes](https://github.com/sindresorhus/query-string/releases)
- [Commits](https://github.com/sindresorhus/query-string/compare/v6.7.0...v6.8.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 18:47:05 -05:00
dependabot-preview[bot]
f3e334ea52 Build(deps): bump semver from 6.2.0 to 6.3.0 (#3821)
Bumps [semver](https://github.com/npm/node-semver) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v6.2.0...v6.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 18:21:49 -05:00
dependabot-preview[bot]
f7c0b9b60c Build(deps-dev): bump eslint-plugin-react from 7.14.2 to 7.14.3 (#3827)
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.14.2 to 7.14.3.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.14.2...v7.14.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 17:58:37 -05:00
dependabot-preview[bot]
d5a1e323b1 Build(deps-dev): bump @babel/plugin-proposal-class-properties (#3826)
Bumps [@babel/plugin-proposal-class-properties](https://github.com/babel/babel) from 7.4.4 to 7.5.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.4...v7.5.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 17:19:07 -05:00
dependabot-preview[bot]
c89cec42f1 Build(deps-dev): bump sazerac from 1.0.0 to 1.1.0 (#3825)
Bumps [sazerac](https://github.com/sazeracjs/sazerac) from 1.0.0 to 1.1.0.
- [Release notes](https://github.com/sazeracjs/sazerac/releases)
- [Changelog](https://github.com/sazeracjs/sazerac/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sazeracjs/sazerac/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 08:39:02 -05:00
dependabot-preview[bot]
36b4e27e22 Build(deps-dev): bump gatsby from 2.13.8 to 2.13.51 (#3824)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.13.8 to 2.13.51.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.13.8...gatsby@2.13.51)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 07:48:58 -05:00
dependabot-preview[bot]
85dc3d1c42 Build(deps-dev): bump gatsby-plugin-react-helmet from 3.1.2 to 3.1.3 (#3822)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-react-helmet) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.1.3/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 07:27:46 -05:00
dependabot-preview[bot]
c4eeede31c Build(deps-dev): bump sinon from 7.3.2 to 7.4.0 (#3820)
Bumps [sinon](https://github.com/sinonjs/sinon) from 7.3.2 to 7.4.0.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-05 07:04:36 -05:00
Caleb Cartwright
0c5c6f9551 fix: runtime TypeError in CodeFactorGrade service (#3815)
Fixes #3813
2019-08-03 18:35:24 +01:00
Pierre-Yves B
8ff783bc68 Handle missing UserDownloads in [ChromeWebStoreUsers] (#3812) 2019-08-01 07:49:51 +01:00
Caleb Cartwright
9eba551842 fix runtime type error in [crates] version (#3811)
* fix: runtime type error in crates version service

* chore: switch CratesVersion tester to use createServiceTester helper

* chore: removed commented out line
2019-07-31 18:19:34 -05:00
dependabot-preview[bot]
9d3c075c04 Build(deps-dev): bump nock from 11.0.0-beta.24 to 11.0.0-beta.30 (#3800)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.24 to 11.0.0-beta.30.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-30 19:32:34 -05:00
dependabot-preview[bot]
1112e7bb19 Build(deps-dev): bump gatsby-plugin-catch-links from 2.1.0 to 2.1.2 (#3807)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-catch-links) from 2.1.0 to 2.1.2.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.1.2/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-29 21:10:29 -05:00
dependabot-preview[bot]
5677218352 Build(deps-dev): bump eslint-plugin-import from 2.18.0 to 2.18.2 (#3804)
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.18.0 to 2.18.2.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.18.0...v2.18.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-29 18:58:46 -05:00
dependabot-preview[bot]
e2d053a1f4 Build(deps-dev): bump eslint-config-standard-react from 7.0.2 to 8.0.0 (#3803)
Bumps [eslint-config-standard-react](https://github.com/feross/eslint-config-standard-react) from 7.0.2 to 8.0.0.
- [Release notes](https://github.com/feross/eslint-config-standard-react/releases)
- [Commits](https://github.com/feross/eslint-config-standard-react/compare/v7.0.2...v8.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-29 18:22:19 -05:00
dependabot-preview[bot]
5572221799 Build(deps-dev): bump @babel/register from 7.4.4 to 7.5.5 (#3802)
Bumps [@babel/register](https://github.com/babel/babel) from 7.4.4 to 7.5.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.4...v7.5.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-29 17:58:17 -05:00
chris48s
75ee413178 Add BaseGraphqlService, support [github] V4 API (#3763)
* add base class for Graphql APIs
* add GithubAuthV4Service + updates to GH token pool
* update github forks to use GithubAuthV4Service
* rename GithubAuthService to GithubAuthV3Service
2019-07-29 21:42:03 +01:00
dependabot-preview[bot]
320de79309 Build(deps-dev): bump mocha from 6.1.4 to 6.2.0 (#3806)
Bumps [mocha](https://github.com/mochajs/mocha) from 6.1.4 to 6.2.0.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v6.1.4...v6.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-29 07:34:19 -05:00
dependabot-preview[bot]
99a4d3456a Build(deps-dev): bump mocha-junit-reporter from 1.23.0 to 1.23.1 (#3799)
Bumps [mocha-junit-reporter](https://github.com/michaelleeallen/mocha-junit-reporter) from 1.23.0 to 1.23.1.
- [Release notes](https://github.com/michaelleeallen/mocha-junit-reporter/releases)
- [Commits](https://github.com/michaelleeallen/mocha-junit-reporter/compare/v1.23.0...v1.23.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-29 07:07:23 -05:00
dependabot-preview[bot]
29fb35a131 Build(deps-dev): bump babel-preset-gatsby from 0.2.6 to 0.2.8 (#3797)
Bumps [babel-preset-gatsby](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/babel-preset-gatsby) from 0.2.6 to 0.2.8.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-preset-gatsby/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/babel-preset-gatsby@0.2.8/packages/babel-preset-gatsby)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-29 06:35:15 -05:00
Caleb Cartwright
a42c9d3517 tests: increase codetally test timeout (#3791) 2019-07-25 22:16:38 -05:00
Paul Melnikow
2177eb7546 Docs: Drop .svg extensions (#3787) 2019-07-25 19:39:35 -05:00
Paul Melnikow
e33cb30a9a Fix regex match in notfound route (#3790)
Fixes #3789
2019-07-25 17:18:02 -05:00
Paul Melnikow
ab7a2106b5 Handle [DynamicJson] parse error (#3783)
Close #3781
2019-07-25 11:35:31 -05:00
Paul Melnikow
09f9f80e6c Use https for [sourceforge] (#3778) 2019-07-25 10:27:51 -05:00
Paul Melnikow
3f891e4a1f Fix timeout logic (#3774)
Close #3773
2019-07-24 22:51:25 -05:00
Paul Melnikow
ead56cdf49 [DynamicJson] Catch jsonpath parse error (#3776)
Closes #3772
2019-07-24 22:07:23 -05:00
Paul Melnikow
c683baa4fb Disable more default Sentry integrations (#3770)
This one is spewing a bunch of recent http calls into each error log.

I get he benefit of these plugins though I'm curious what resources they might be using. And in this case, don't want the requests to end up e.g. in a GitHub issue.
2019-07-24 20:39:07 -05:00
Paul Melnikow
a120e5df9b Upgrade to new Sentry SDKs; fix error reporting detail (#3764) 2019-07-24 18:58:22 -05:00
Pierre-Yves B
777a5ff23c Cover missing PHP version requirement in [PackagistPhpVersion] (#3768) 2019-07-24 22:18:13 +01:00
dependabot-preview[bot]
6b30daaeea Build(deps-dev): bump @babel/preset-env from 7.5.2 to 7.5.5 (#3756)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.5.2 to 7.5.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.5.2...v7.5.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-24 15:49:35 -05:00
dependabot-preview[bot]
800d8ef861 Build(deps-dev): bump @babel/plugin-proposal-object-rest-spread (#3757)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.5.1 to 7.5.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.5.1...v7.5.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-24 13:06:58 -05:00
Paul Melnikow
cfbd2c30df SVG by default (#3717)
Make cleaner badge URLs by omitting the `.svg` extension.

Closes #2674
2019-07-24 12:57:39 -05:00
Paul Melnikow
e6f8c4ed65 Fix extraneous brackets in query string builder (#3766)
Fix #3765
2019-07-24 12:13:50 -05:00
Paul Melnikow
3964eb5cb0 Remove use of deprecated Domain API (#3762)
Use of this feature [has been discouraged for a long time](https://nodejs.org/api/domain.html).

Since most of our code is now bubbling through async, we aren't really getting these "vendor errors" anymore.

Errors that _do_ bubble up through the services have been reported to Sentry since #3706, though they seem to be missing a bunch of their stack traces. Sentry also seems to be combining unrelated internal errors. (https://github.com/badges/shields/issues/3709#issuecomment-514299441) Maybe this will help.
2019-07-23 16:43:09 -05:00
dependabot-preview[bot]
2895aaf93c Build(deps-dev): bump gatsby-plugin-react-helmet from 3.1.0 to 3.1.2 (#3755)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-react-helmet) from 3.1.0 to 3.1.2.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.1.2/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-23 22:19:17 +01:00
dependabot-preview[bot]
c7cae03d7d Build(deps-dev): bump eslint-plugin-cypress from 2.2.1 to 2.6.0 (#3754)
Bumps [eslint-plugin-cypress](https://github.com/cypress-io/eslint-plugin-cypress) from 2.2.1 to 2.6.0.
- [Release notes](https://github.com/cypress-io/eslint-plugin-cypress/releases)
- [Commits](https://github.com/cypress-io/eslint-plugin-cypress/compare/v2.2.1...v2.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-23 22:05:19 +01:00
dependabot-preview[bot]
b214a28822 Build(deps-dev): bump @typescript-eslint/eslint-plugin (#3753)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v1.13.0/packages/eslint-plugin)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-23 21:58:13 +01:00
Paul Melnikow
0e181f16b5 Rewrite QueryStringBuilder using hooks (#3740) 2019-07-23 12:08:19 -05:00
Pierre-Yves B
883b025555 Made popout-square check more specific (#3760) 2019-07-23 17:25:11 +01:00
dependabot-preview[bot]
8fa0ab13c0 Build(deps-dev): bump gatsby-plugin-page-creator from 2.1.1 to 2.1.5 (#3752)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-page-creator) from 2.1.1 to 2.1.5.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.1.5/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-23 10:32:07 -05:00
dependabot-preview[bot]
acd2d4b79f Build(deps-dev): bump @typescript-eslint/parser from 1.12.0 to 1.13.0 (#3750)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v1.13.0/packages/parser)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-23 07:14:51 -05:00
dependabot-preview[bot]
f305c05cc1 Build(deps-dev): bump @types/enzyme from 3.10.2 to 3.10.3 (#3748)
Bumps [@types/enzyme](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/enzyme) from 3.10.2 to 3.10.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/enzyme)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-22 21:22:41 -05:00
Caleb Cartwright
21a67b9511 chore: fix teamcity example badge listings (#3759)
Refs https://github.com/badges/shields/pull/3717#discussion_r305633151
2019-07-22 19:19:26 -05:00
dependabot-preview[bot]
f251de395d Build(deps): bump config from 3.1.0 to 3.2.2 (#3751)
Bumps [config](https://github.com/lorenwest/node-config) from 3.1.0 to 3.2.2.
- [Release notes](https://github.com/lorenwest/node-config/releases)
- [Changelog](https://github.com/lorenwest/node-config/blob/master/History.md)
- [Commits](https://github.com/lorenwest/node-config/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-22 15:14:22 -05:00
Paul Melnikow
28b8836595 Unify the ESLint config (#3743)
Adding TypeScript to the frontend and a `.d.ts` file to `core` (see #3742) has multiplied out the different combinations of lint rules. ESLint has support for file-pattern-based overrides, which we've used in some places, but we've also maintained a separate eslintrc for `frontend/`.

This merges the config together, with the strategy of putting all the rules at the top level except where they conflict, and applying settings to exactly the files where they should apply.

This introduces a few new errors in the server but they are true positives – hoisting and lowercase class names – things we don't really need to be doing).
2019-07-22 15:06:38 -05:00
Pierre-Yves B
ecb85cef53 Remove popout styles (#3747)
* Remove popout styles

* Make popout-square fall back to flat-square
2019-07-22 20:56:07 +01:00
Paul Melnikow
ec6512b7ba Rewrite RequestMarkupButton using hooks (#3739) 2019-07-21 13:48:49 -05:00
Pierre-Yves B
345c26f72d Handle packages with no released versions in [PackagistVersion] (#3746) 2019-07-20 17:52:53 +01:00
Paul Melnikow
236decac29 Rewrite Main using hooks (#3738) 2019-07-19 12:27:25 -05:00
Paul Melnikow
4090ab8a01 Rewrite SugggestionAndSearch using hooks (#3741) 2019-07-19 12:10:10 -05:00
Paul Melnikow
88fc4a751c Initial adoption of TypeScript in the frontend (#3722)
Ref #3657
2019-07-17 23:11:51 -04:00
Paul Melnikow
d4e17d4e94 Rewrite PathBuilder using hooks (#3721) 2019-07-17 22:02:01 -04:00
Paul Melnikow
5d3d78b209 Rewrite Customizer using hooks (#3720) 2019-07-17 21:15:30 -04:00
Paul Melnikow
be275b9f13 Rewrite CopiedContentIndicator using hooks (#3719) 2019-07-17 16:16:42 -04:00
Pierre-Yves B
3dbe655611 Display one decimal for metrics smaller than 10 (#3735)
* Display one decimal for metrics smaller than 10

* Update test validators

* Run Prettier

* Update GitHub regexes
2019-07-17 20:00:29 +01:00
dependabot-preview[bot]
e556ac2793 Build(deps): bump simple-icons from 1.10.0 to 1.11.0 (#3728)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-16 19:40:51 -05:00
dependabot-preview[bot]
c7130bec61 Build(deps-dev): bump babel-preset-gatsby from 0.2.1 to 0.2.6 (#3733)
Bumps [babel-preset-gatsby](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/babel-preset-gatsby) from 0.2.1 to 0.2.6.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/babel-preset-gatsby/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/babel-preset-gatsby@0.2.6/packages/babel-preset-gatsby)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-16 19:05:38 -05:00
dependabot-preview[bot]
da36dcf195 Build(deps-dev): bump portfinder from 1.0.20 to 1.0.21 (#3730)
Bumps [portfinder](https://github.com/indexzero/node-portfinder) from 1.0.20 to 1.0.21.
- [Release notes](https://github.com/indexzero/node-portfinder/releases)
- [Commits](https://github.com/indexzero/node-portfinder/compare/v1.0.20...v1.0.21)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-16 23:02:18 +02:00
dependabot-preview[bot]
d9aefc61bf Build(deps): bump prom-client from 11.5.2 to 11.5.3 (#3731)
Bumps [prom-client](https://github.com/siimon/prom-client) from 11.5.2 to 11.5.3.
- [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/v11.5.2...v11.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-16 22:49:58 +02:00
dependabot-preview[bot]
7ba56fa96d Build(deps-dev): bump cypress from 3.3.2 to 3.4.0 (#3729)
Bumps [cypress](https://github.com/cypress-io/cypress) from 3.3.2 to 3.4.0.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Commits](https://github.com/cypress-io/cypress/compare/v3.3.2...v3.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-16 22:15:02 +02:00
dependabot-preview[bot]
aa03fdcdb4 Build(deps): bump semver from 6.1.2 to 6.2.0 (#3732)
Bumps [semver](https://github.com/npm/node-semver) from 6.1.2 to 6.2.0.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v6.1.2...v6.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-16 20:11:17 +01:00
dependabot-preview[bot]
cde36f642d Build(deps-dev): bump react-modal from 3.8.2 to 3.9.1 (#3727)
Bumps [react-modal](https://github.com/reactjs/react-modal) from 3.8.2 to 3.9.1.
- [Release notes](https://github.com/reactjs/react-modal/releases)
- [Changelog](https://github.com/reactjs/react-modal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-modal/compare/v3.8.2...v3.9.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-16 08:31:27 -05:00
Paul Melnikow
3bce0b0eee Capitalize Open Collective in badge listing (#3734) 2019-07-15 22:27:16 +01:00
dependabot-preview[bot]
f44352f74a Build(deps-dev): bump gatsby-plugin-styled-components (#3726)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/HEAD/packages/gatsby-plugin-styled-components) from 3.1.0 to 3.1.2.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.1.2/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-15 07:37:26 -05:00
dependabot-preview[bot]
289e69c475 Build(deps-dev): bump jsdoc from 3.6.2 to 3.6.3 (#3725)
Bumps [jsdoc](https://github.com/jsdoc/jsdoc) from 3.6.2 to 3.6.3.
- [Release notes](https://github.com/jsdoc/jsdoc/releases)
- [Changelog](https://github.com/jsdoc/jsdoc/blob/master/CHANGES.md)
- [Commits](https://github.com/jsdoc/jsdoc/compare/3.6.2...3.6.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-15 07:22:12 -05:00
dependabot-preview[bot]
5ff5462e8d Build(deps-dev): bump nock from 11.0.0-beta.20 to 11.0.0-beta.24 (#3723)
Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.20 to 11.0.0-beta.24.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-15 06:47:35 -05:00
Paul Melnikow
4e4e7be804 Update lockfile with npm audit fixes (#3718) 2019-07-14 19:30:00 -04:00
Paul Melnikow
b493fbf70e Add warnings alongside deprecated URL patterns (#3715)
Ref #3714
2019-07-14 19:14:19 -04:00
Paul Melnikow
6a2f384860 Update [Sonar] routes: metric first, and server in the query string (#3696)
This is the preferred way we’re handling server URLs: in the query string.

While we still have a mix of these, I’ve argued this way is better for these reasons:

1. It allows us to make the URLs a bit more standardized across services.
2. It makes the routes unambiguous.
3. It requires less code.

While it introduces a URL-encoding requirement on the parameter, I think these tradeoffs are worth it.
2019-07-14 17:06:14 -04:00
Caleb Cartwright
bd8b1ead59 tests: remove service tests for dropped static png routes (#3712) 2019-07-13 17:40:17 +01:00
Jan Škrášek
39d47a10b4 service/packagist: normalize stability suffixes (#3699) 2019-07-13 11:02:43 -05:00
Pierre-Yves B
9576ba8fc3 Split [Conda] tests (#3711) 2019-07-13 10:55:41 -05:00
Pierre-Yves B
102db63d46 Split [pypi] tests (#3704)
* Split [pypi] tests

* Changed filenames to match previous class names
2019-07-13 10:45:58 -05:00
Paul Melnikow
6cbc7b587a Document the production Redis hosting (#3710)
Close #3332
2019-07-13 08:39:07 -05:00
Paul Melnikow
ec0264dfb7 Fix Redis prod issue for Node 9 (#3707)
Encountered while testing #3332
2019-07-12 19:51:05 -04:00
Paul Melnikow
153732756c Log internal errors to Sentry (#3706)
Fix #3688
2019-07-12 19:40:46 -04:00
Paul Melnikow
65afff40d4 Fix up Redis config (#3705)
- Move to private
- Fix validation
- Don't log the URL

Ref #3332
2019-07-12 19:12:49 -04:00
Paul Melnikow
84063f8ae3 Switch to ioredis, and update RedisTokenPersistence to use a set instead of a list (#3668)
Also add a script for importing a batch of tokens.

Ref #3332
2019-07-12 18:30:24 -04:00
Pierre-Yves B
5fb429a1ef Split [Jetbrains] tests (#3702)
* Split [Jetbrains] tests

* Removed inaccessible/invalid tests
2019-07-12 22:59:21 +01:00
Pierre-Yves B
69862549a8 Split [LGTM] tests (#3703) 2019-07-12 22:22:56 +01:00
Pierre-Yves B
12db962e50 Split [Bitbucket] tests (#3701) 2019-07-12 21:09:29 +01:00
Paul Melnikow
46ac947e9b Refactor auth config checks in another test (#3698)
This is one more like #3694.

Ref #3652 #3393
2019-07-11 20:00:20 -04:00
Paul Melnikow
5d20a371d1 Update serverSecrets reference in legacy monitor (#3697)
Ref #3652 #3393
2019-07-11 19:41:22 -04:00
Pierre-Yves B
0a276f692f Colorize [OSSLifecycle] badge (#3695)
* Updated examples

* Ran Prettier again
2019-07-11 23:28:21 +01:00
Paul Melnikow
ace66f457d Refactor auth config checks within tests (#3694)
Ref #3652 #3393
2019-07-11 18:11:34 -04:00
Paul Melnikow
e2608a6570 Refactor GitHub OAuth credential handling (#3693)
Continues the work of #3652.
2019-07-11 18:04:53 -04:00
Paul Melnikow
930a7219b0 Refactor [bitbucket] secrets (#3691)
Continues the work of #3652.

Since Bitbucket is the only service to use two sets of credentials like this, it seems to make the most sense to build a very local solution.
2019-07-11 17:56:51 -04:00
Paul Melnikow
b2e5aa9208 Cache raster redirects longer (#3690)
Haven't seen error reports on these, so let's cache these a bit longer to reduce our server load.
2019-07-11 16:57:21 -04:00
Pierre-Yves B
7bdda90c0f Documentation for OSS Lifecycle (#3689) 2019-07-11 21:23:57 +01:00
chris48s
38cdc0033f adopt JSDoc, eslint-plugin-jsdoc (#3645)
eslint-plugin-jsdoc:
- install eslint-plugin-jsdoc
- config file
- fix lint/style errors

JSDoc:
- add JSDoc as a dev dependency
- get everything rendering nicely with JSDoc
- config, build command + ignores
2019-07-11 20:14:47 +01:00
Duane O'Brien
ad7023bcbe Make the osslifecycle badge company-agnostic (#3618)
* Make the osslifecycle badge company-agnostic 

Removes references to Netflix in the example titles of the osslifecycle badge
To make the badge more generic and easier to use by companies besides Netflix, the examples should remove Netflix from the title.

* Adding Netflix back in as a keyword, to make the badge easily searchable for people who remember it with the old title.
2019-07-11 19:08:43 +01:00
Chintalagiri Shashank
a9d0f0d323 Updates *GPL licenses to new SPDX ids and adds additional aliases, run service tests for [apm aur bowerlicense cocoapodslicense cpanlicense cran crates ctan dublicense eclipsemarketplacelicense githublicense hexpm npmlicense packagistlicense pypilicense] (#3686)
* Updated GPL, LGPL, and AGPL licence IDs to the SPEX 3.5 specification.

* Add GPL, LGPL, and AGPL aliases in the format in which they are used in Python classifiers.
2019-07-10 15:38:00 -05:00
Paul Melnikow
ce0ddf93fc Inject secrets into the services (#3652)
This is a reworking of #3410 based on some feedback @calebcartwright left on that PR.

The goals of injecting the secrets are threefold:

1. Simplify testing
2. Be consistent with all of the other config (which is injected)
3. Encapsulate the sensitive auth-related code in one place so it can be studied and tested thoroughly

- Rather than add more code to BaseService to handle authorization logic, it delegates that to an AuthHelper class.
- When the server starts, it fetches the credentials from `config` and injects them into `BaseService.register()` which passes them to `invoke()`.
- In `invoke()` the service's auth configuration is checked (`static get auth()`, much like `static get route()`).
- If the auth config is present, an AuthHelper instance is created and attached to the new instance.
- Then within the service, the password, basic auth config, or bearer authentication can be accessed via e.g. `this.authHelper.basicAuth` and passed to `this._requestJson()` and friends.
- Everything is being done very explicitly, so it should be very clear where and how the configured secrets are being used.
- Testing different configurations of services can now be done by injecting the config into `invoke()` in `.spec` files instead of mocking global state in the service tests as was done before. See the new Jira spec files for a good example of this.

Ref #3393
2019-07-09 23:14:36 -04:00
dependabot-preview[bot]
3324a4a162 Build(deps-dev): bump @babel/plugin-proposal-object-rest-spread (#3670)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.4.4 to 7.5.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.4...v7.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-09 19:49:25 +01:00
dependabot-preview[bot]
ba560fe540 Build(deps-dev): bump danger from 8.0.0 to 9.0.3 (#3673)
Bumps [danger](https://github.com/danger/danger-js) from 8.0.0 to 9.0.3.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/8.0.0...9.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-09 19:41:27 +01:00
dependabot-preview[bot]
96b7726148 Build(deps-dev): bump gatsby from 2.9.4 to 2.13.8 (#3680)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.9.4 to 2.13.8.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/compare/gatsby@2.9.4...gatsby@2.13.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-09 19:35:04 +01:00
dependabot-preview[bot]
c08c28ebd9 Build(deps-dev): bump @babel/preset-env from 7.4.5 to 7.5.2 (#3682)
Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.4.5 to 7.5.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.5...v7.5.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-09 04:56:09 -05:00
dependabot-preview[bot]
c023ceda14 Build(deps-dev): bump styled-components from 4.3.1 to 4.3.2 (#3676)
Bumps [styled-components](https://github.com/styled-components/styled-components) from 4.3.1 to 4.3.2.
- [Release notes](https://github.com/styled-components/styled-components/releases)
- [Changelog](https://github.com/styled-components/styled-components/blob/master/CHANGELOG.md)
- [Commits](https://github.com/styled-components/styled-components/compare/v4.3.1...v4.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-08 21:12:56 -05:00
dependabot-preview[bot]
29fc9161e2 Build(deps-dev): bump cypress from 3.3.1 to 3.3.2 (#3678)
Bumps [cypress](https://github.com/cypress-io/cypress) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Commits](https://github.com/cypress-io/cypress/compare/v3.3.1...v3.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-08 21:24:07 +02:00
Pierre-Yves B
8c4cb41b6d New [Gerrit] badge (#3667) 2019-07-08 19:21:57 +01:00
Paul Melnikow
738d4c78bc Ensure Joi is imported as @hapi/joi [cirrus] (#3681)
* Ensure Joi is imported as @hapi/joi [cirrus]

I noticed this import failed in #3675. Maybe we've finally dropped the last copy of the old joi?

* Ignore dangerfile
2019-07-08 13:09:31 -04:00
dependabot-preview[bot]
294aa1e1df Build(deps-dev): bump eslint-plugin-import from 2.17.3 to 2.18.0; autofixes (#3671)
* Build(deps-dev): bump eslint-plugin-import from 2.17.3 to 2.18.0

Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.17.3 to 2.18.0.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.17.3...v2.18.0)

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

* Autofixes
2019-07-08 12:13:46 -04:00
dependabot-preview[bot]
a47d9a9db3 Build(deps-dev): bump eslint-plugin-promise from 4.1.1 to 4.2.1 (#3674)
Bumps [eslint-plugin-promise](https://github.com/xjamundx/eslint-plugin-promise) from 4.1.1 to 4.2.1.
- [Release notes](https://github.com/xjamundx/eslint-plugin-promise/releases)
- [Changelog](https://github.com/xjamundx/eslint-plugin-promise/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xjamundx/eslint-plugin-promise/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-08 11:52:19 -04:00
dependabot-preview[bot]
e9521dd58f Build(deps-dev): bump babel-preset-gatsby from 0.2.0 to 0.2.1 (#3672)
Bumps babel-preset-gatsby from 0.2.0 to 0.2.1.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-08 11:45:30 -04:00
Paul Melnikow
aa135d370f Auto-annotate live and mock tests (#3661)
Close #2555
2019-07-07 17:06:01 -04:00
Paul Melnikow
3bf97a6a12 Per node support policy, drop tests for Node 11 (#3665) 2019-07-07 16:59:27 -04:00
Paul Melnikow
9b3db0774b Deprecate shields-server.com domain (#3666)
Now that these s0.server.shields.io entries are set up through the main DNS on Cloudflare, we don't need the shields-server.com domain anymore. One less thing to maintain.
2019-07-07 16:37:42 -04:00
Paul Melnikow
9b6a51b61e Convert a format to pattern in [githubpackagejson] (#3660)
This now relies on the order in which these are registered, though that seems okay. Exporting them as an array guarantees that.

Ref #3329
2019-07-07 12:41:30 -04:00
Paul Melnikow
eec904c262 Fix raster redirect and drop the legacy static .png route (#3659) 2019-07-07 11:49:21 -04:00
Paul Melnikow
66c7f13e38 Drop gif + png, and redirect png to raster.shields.io (#3644)
1. Remove rasterization support from the server. This responsibility is delegated to a raster server which proxies the SVG badges and renders them.
2. When a raster server URL is configured, 301 redirect all .png badges to the identical URL on the raster server.
    `https://img.shields.io/npm/v/express.png?style=flat-square` ↪️`https://raster.shields.io/npm/v/express.png?style=flat-square`
3. For configured redirects, redirect to the canonical URL on the raster server.
    `https://img.shields.io/vso/build/totodem/8cf3ec0e-d0c2-4fcd-8206-ad204f254a96/2.png?style=flat-square`
    ↪️`https://img.shields.io/azure-devops/build/totodem/8cf3ec0e-d0c2-4fcd-8206-ad204f254a96/2.png?style=flat-square`
4. Redirect the "legacy badge old version" to the appropriate URL on the raster server.
5. When no raster server is configured (e.g. PRs), render an SVG containing **404 | raster badges not available** for all `.png` badges. (Note that the raster server can be self-hosted; however, this is deferred to a later PR.)
5. Drop support for jpg and gif which are very infrequently used (see #3112). Render an SVG containing **410 | jpg no longer available**.
7. ~~Remove raster dependencies.~~ Remove the raster cache (which is only used in the CLI, and therefore pointless).
8. Move the LRUCache code out of the npm package.
8. A wee bit of refactoring in `server.js`.

Ref #3112
Close #3631
2019-07-06 16:41:46 -04:00
Pierre-Yves B
c6ef885b75 Footer update (#3655)
* Reworded footer

* Added metrics link
2019-07-06 17:14:13 +01:00
Paul Melnikow
093d9cd368 Minor refactor: expose custom promisify function from legacy request handler (#3650)
Cherry-picked from #3410; should simplify reworking it.
2019-07-05 21:26:05 -04:00
Paul Melnikow
9346548850 Refactor [BitbucketPullRequest] (#3649)
This encapsulates the fetch methods slightly better. Cherry-picked from #3410, which needs to be reworked. This change should simplify dropping in the new auth method when that happens.
2019-07-05 17:40:43 -04:00
Paul Melnikow
c817e69775 Minor refactor in [azuredevopstests] (#3651)
Cherry-picked from #3410; should simplify reworking it.
2019-07-05 16:52:17 -04:00
Paul Melnikow
5d06503844 Update Zeit members list (#3646) 2019-07-05 14:51:57 -04:00
Paul Melnikow
f693ef019d Document raster server production hosting (#3643)
Ref #3631
2019-07-05 13:54:05 -04:00
Danial
8f11291b98 Fix for-the-badge spacing, uppercase left, right instead of text[] variables (#3640) 2019-07-05 11:59:02 +12:00
Pierre-Yves B
77b4551716 Support other [Bugzilla] instances (#3633) 2019-07-04 22:57:51 +01:00
Paul Melnikow
d3261be1db Docker: Don't installl Cypress (#3634)
Noticed this in the Docker Hub build log:
https://cloud.docker.com/u/shieldsio/repository/registry-1.docker.io/shieldsio/shields/builds/de14f15e-0f10-4842-9ad2-42b8558bc2ff

Ref #3558
2019-07-02 21:17:10 -04:00
chris48s
0d3266a0ad JSDoc comments for service test runner (#3630) 2019-07-02 12:41:28 -04:00
dependabot-preview[bot]
ec17c4d67e Build(deps-dev): bump js-yaml-loader from 1.2.0 to 1.2.2 (#3628)
* Build(deps-dev): bump js-yaml-loader from 1.2.0 to 1.2.2

Bumps [js-yaml-loader](https://github.com/wwilsman/js-yaml-loader) from 1.2.0 to 1.2.2.
- [Release notes](https://github.com/wwilsman/js-yaml-loader/releases)
- [Commits](https://github.com/wwilsman/js-yaml-loader/compare/v1.2.0...v1.2.2)

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

* clarify how service defs are loaded
2019-07-01 18:39:31 -04:00
chris48s
f29da0abdd JSDoc comments for token pool (#3632) 2019-07-01 17:55:08 -04:00
Caleb Cartwright
ea865436a1 add [Sonar] badges for various test metrics (#3571)
* feat: add SonarTests badges

* chore: remove commented out line

* refactor: update SonarTestsSummary to override transform
2019-07-01 15:46:51 -05:00
dependabot-preview[bot]
0cf00d963d Build(deps-dev): bump gatsby-plugin-remove-trailing-slashes (#3629)
Bumps [gatsby-plugin-remove-trailing-slashes](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-remove-trailing-slashes) from 2.0.11 to 2.1.0.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-remove-trailing-slashes/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-remove-trailing-slashes@2.1.0/packages/gatsby-plugin-remove-trailing-slashes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 19:47:22 +01:00
dependabot-preview[bot]
e20e1c5064 Build(deps-dev): bump gatsby-plugin-catch-links from 2.0.15 to 2.1.0 (#3626)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-catch-links) from 2.0.15 to 2.1.0.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.1.0/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 19:26:27 +01:00
dependabot-preview[bot]
8cba5b18a5 Build(deps-dev): bump react-modal from 3.8.1 to 3.8.2 (#3623)
Bumps [react-modal](https://github.com/reactjs/react-modal) from 3.8.1 to 3.8.2.
- [Release notes](https://github.com/reactjs/react-modal/releases)
- [Changelog](https://github.com/reactjs/react-modal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-modal/compare/v3.8.1...v3.8.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 19:18:17 +01:00
dependabot-preview[bot]
412ecddfec Build(deps-dev): bump eslint-plugin-react-hooks from 1.6.0 to 1.6.1 (#3627)
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 1.6.0 to 1.6.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/HEAD/packages/eslint-plugin-react-hooks)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 19:04:36 +01:00
dependabot-preview[bot]
7aaf42ba1b Build(deps-dev): bump eslint-config-prettier from 5.0.0 to 6.0.0 (#3625)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v5.0.0...v6.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 18:56:58 +01:00
dependabot-preview[bot]
7e2726cd9e Build(deps-dev): bump concurrently from 4.1.0 to 4.1.1 (#3624)
Bumps [concurrently](https://github.com/kimmobrunfeldt/concurrently) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kimmobrunfeldt/concurrently/releases)
- [Commits](https://github.com/kimmobrunfeldt/concurrently/compare/v4.1.0...v4.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 18:44:26 +01:00
dependabot-preview[bot]
9f9e949f85 Build(deps-dev): bump eslint-plugin-react from 7.13.0 to 7.14.2 (#3621)
Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.13.0 to 7.14.2.
- [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases)
- [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.13.0...v7.14.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 18:37:53 +01:00
dependabot-preview[bot]
acd3dedbb7 Build(deps-dev): bump eslint-plugin-sort-class-members (#3620)
Bumps [eslint-plugin-sort-class-members](https://github.com/bryanrsmith/eslint-plugin-sort-class-members) from 1.4.0 to 1.5.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.4.0...v1.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 12:26:08 -05:00
dependabot-preview[bot]
f71c47edcd Build(deps): bump simple-icons from 1.9.28 to 1.10.0 (#3622)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.28 to 1.10.0.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-07-01 11:39:20 -04:00
Paul Melnikow
0f19806c58 Bump nock from 11.0.0.beta-14 to 11.0.0.beta-20 (#3616)
* Bump icedfrisby and icedfrisby-nock

* Bump nock from 11.0.0.beta-14 to 11.0.0.beta-20

Hoping the changes from #3615 will fix the issues that appeared at https://github.com/badges/shields/pull/3552#issuecomment-504610847

* Fix apm tests

* Fix githubcommitstatus
2019-06-28 15:50:17 -04:00
Paul Melnikow
6c21d86194 Bump icedfrisby and icedfrisby-nock (#3615) 2019-06-28 14:04:03 -04:00
chris48s
d78edaf5b5 add/improve some JSDoc comments on core API (#3595) 2019-06-25 22:42:01 +01:00
dependabot-preview[bot]
1ae6a0fd16 Build(deps): bump prom-client from 11.3.0 to 11.5.2 (#3604)
Bumps [prom-client](https://github.com/siimon/prom-client) from 11.3.0 to 11.5.2.
- [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/v11.3.0...v11.5.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-25 20:44:00 +02:00
dependabot-preview[bot]
34a6096f5e Build(deps): bump @hapi/joi from 15.0.3 to 15.1.0 (#3605)
Bumps [@hapi/joi](https://github.com/hapijs/joi) from 15.0.3 to 15.1.0.
- [Release notes](https://github.com/hapijs/joi/releases)
- [Changelog](https://github.com/hapijs/joi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hapijs/joi/compare/v15.0.3...v15.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-25 10:48:11 -05:00
dependabot-preview[bot]
aca051c968 Build(deps-dev): bump gatsby-plugin-page-creator from 2.0.13 to 2.1.1 (#3607)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-page-creator) from 2.0.13 to 2.1.1.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.1.1/packages/gatsby-plugin-page-creator)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-25 06:35:36 -05:00
dependabot-preview[bot]
b6a72cdb58 Build(deps): bump semver from 6.1.1 to 6.1.2 (#3603)
Bumps [semver](https://github.com/npm/node-semver) from 6.1.1 to 6.1.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v6.1.1...v6.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-24 22:24:50 -05:00
dependabot-preview[bot]
7ed502e23d Build(deps-dev): bump enzyme from 3.9.0 to 3.10.0 (#3579)
* Build(deps-dev): bump enzyme from 3.9.0 to 3.10.0

Bumps [enzyme](https://github.com/airbnb/enzyme/tree/HEAD/packages/enzyme) from 3.9.0 to 3.10.0.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/commits/enzyme@3.10.0/packages/enzyme)

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

* tests: tweak assertion on emtpy attribute
2019-06-24 21:09:04 -05:00
dependabot-preview[bot]
6fc6cf7acf Build(deps-dev): bump gatsby-plugin-styled-components (#3602)
Bumps [gatsby-plugin-styled-components](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-styled-components) from 3.0.7 to 3.1.0.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-styled-components/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-styled-components@3.1.0/packages/gatsby-plugin-styled-components)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-24 19:40:12 -05:00
dependabot-preview[bot]
5ddd28143e Build(deps-dev): bump snap-shot-it from 7.7.0 to 7.8.0 (#3601)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 7.7.0 to 7.8.0.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v7.7.0...v7.8.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-24 19:17:23 -05:00
dependabot-preview[bot]
479eaf4673 Build(deps-dev): bump babel-preset-gatsby from 0.1.11 to 0.2.0 (#3598)
Bumps babel-preset-gatsby from 0.1.11 to 0.2.0.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-24 15:02:23 -05:00
dependabot-preview[bot]
38bc46db7c Build(deps-dev): bump gatsby-plugin-react-helmet from 3.0.12 to 3.1.0 (#3597)
Bumps [gatsby-plugin-react-helmet](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-react-helmet) from 3.0.12 to 3.1.0.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-react-helmet/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-react-helmet@3.1.0/packages/gatsby-plugin-react-helmet)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-24 14:28:19 -05:00
Caleb Cartwright
96dde9919d rollback nock to 11.0.0-beta.14 (#3594)
* chore(deps): rollback nock to 11.0.0-beta.14

* chore: add package-lock.json

* Run npm install, to try to fix deploy issue
2019-06-23 17:16:41 -04:00
Pierre-Yves B
1e207f1886 Tutorial improvements and fixes (#3593) 2019-06-23 17:52:41 +01:00
Caleb Cartwright
c312eae3e3 feat: add CodeFactor grade badge (#3588) 2019-06-22 09:13:34 -05:00
dependabot-preview[bot]
95b6e48bff Build(deps-dev): bump nock from 11.0.0-beta.14 to 11.0.0-beta.19 (#3552)
* Build(deps-dev): bump nock from 11.0.0-beta.14 to 11.0.0-beta.19

Bumps [nock](https://github.com/nock/nock) from 11.0.0-beta.14 to 11.0.0-beta.19.
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/beta/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/commits)

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

* Fix one test

* Update for breaking change in nock api

* Always use got without retries in tests
2019-06-21 10:45:34 -04:00
Caleb Cartwright
fe76a55e2c tests: fix some jenkins service tests (#3590) 2019-06-20 08:59:55 -04:00
dependabot-preview[bot]
5c67bfe0e0 Build(deps-dev): bump enzyme-adapter-react-16 from 1.13.1 to 1.14.0 (#3575)
Bumps [enzyme-adapter-react-16](https://github.com/airbnb/enzyme/tree/HEAD/packages/enzyme-adapter-react-16) from 1.13.1 to 1.14.0.
- [Release notes](https://github.com/airbnb/enzyme/releases)
- [Changelog](https://github.com/airbnb/enzyme/blob/master/CHANGELOG.md)
- [Commits](https://github.com/airbnb/enzyme/commits/enzyme-adapter-react-16@1.14.0/packages/enzyme-adapter-react-16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-17 20:00:36 -05:00
dependabot-preview[bot]
6342db52a8 Build(deps-dev): bump eslint-config-prettier from 4.3.0 to 5.0.0 (#3583)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 4.3.0 to 5.0.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v4.3.0...v5.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-17 19:45:43 -05:00
dependabot-preview[bot]
d732b937c9 Build(deps-dev): bump prettier from 1.17.1 to 1.18.2 (#3580)
* Build(deps-dev): bump prettier from 1.17.1 to 1.18.2

Bumps [prettier](https://github.com/prettier/prettier) from 1.17.1 to 1.18.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.17.1...1.18.2)

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

* chore: prettier
2019-06-17 19:15:44 -05:00
dependabot-preview[bot]
a4e2df80f8 Build(deps-dev): bump gatsby from 2.9.1 to 2.9.4 (#3582)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.9.1 to 2.9.4.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby@2.9.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-17 21:31:10 +02:00
dependabot-preview[bot]
eaa15a9f0b Build(deps): bump query-string from 6.5.0 to 6.7.0 (#3577)
Bumps [query-string](https://github.com/sindresorhus/query-string) from 6.5.0 to 6.7.0.
- [Release notes](https://github.com/sindresorhus/query-string/releases)
- [Commits](https://github.com/sindresorhus/query-string/compare/v6.5.0...v6.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-17 21:19:41 +02:00
dependabot-preview[bot]
a6d82daef3 Build(deps-dev): bump snap-shot-it from 7.4.4 to 7.7.0 (#3581)
Bumps [snap-shot-it](https://github.com/bahmutov/snap-shot-it) from 7.4.4 to 7.7.0.
- [Release notes](https://github.com/bahmutov/snap-shot-it/releases)
- [Commits](https://github.com/bahmutov/snap-shot-it/compare/v7.4.4...v7.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-17 21:07:30 +02:00
dependabot-preview[bot]
8deabe6245 Build(deps-dev): bump husky from 2.3.0 to 2.4.1 (#3578)
Bumps [husky](https://github.com/typicode/husky) from 2.3.0 to 2.4.1.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v2.3.0...v2.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-17 07:42:29 -05:00
dependabot-preview[bot]
aaed6fc79c Build(deps-dev): bump eslint-plugin-node from 9.0.1 to 9.1.0 (#3576)
Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 9.0.1 to 9.1.0.
- [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases)
- [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v9.0.1...v9.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-17 07:33:47 -05:00
Caleb Cartwright
e2287c77b3 docs: add labels to github issue templates (#3573) 2019-06-16 15:38:31 -05:00
Pierre-Yves B
0701f02bea Removed unused xml2js dependency (#3574) 2019-06-16 20:07:37 +01:00
Caleb Cartwright
c9917c0176 feat: add scoped package support for jsdeliver npm hits (#3570) 2019-06-16 19:21:48 +01:00
Caleb Cartwright
6fb6cfaa40 tests: fix Azure DevOps build test (#3569) 2019-06-16 19:16:37 +01:00
Reece Dunham
0808a70d6d Added [Cirrus] CI badge support (#3502)
* add base (needs tweaking)

* more work

* updates / more work

* fix minor thing

* handle

* add test

* Fix

* get rid of svg scraper

* Fixed Cirrus badge

Use JSON endpoint

* Rename cirrus.test.js to cirrus.tester.js

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update cirrus.service.js

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.tester.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.tester.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.tester.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.tester.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Caleb Cartwright <calebcartwright@users.noreply.github.com>

* Update services/cirrus/cirrus.service.js

Co-Authored-By: Fedor Korotkov <fedor.korotkov@gmail.com>
2019-06-15 14:30:47 -05:00
chris48s
703371dd78 fix [wordpress] /v redirect (closes #3564) (#3565) 2019-06-13 16:48:38 +01:00
Caleb Cartwright
d37caea7aa fix(BitbucketIssues): switch to v2 API from deprecated v1 API (#3563) 2019-06-12 17:27:17 -05:00
dependabot-preview[bot]
b6fe3a3f9c Build(deps-dev): bump gatsby from 2.5.7 to 2.9.1 (#3562)
Bumps [gatsby](https://github.com/gatsbyjs/gatsby) from 2.5.7 to 2.9.1.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-12 12:27:07 -05:00
dependabot-preview[bot]
8a3b9f6f1e Build(deps-dev): bump danger from 7.1.4 to 8.0.0 (#3553)
Bumps [danger](https://github.com/danger/danger-js) from 7.1.4 to 8.0.0.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.1.4...8.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-12 12:12:03 -05:00
Caleb Cartwright
885dc9a1f4 Update CI config to cache/skip Cypress binary (#3540)
* ci: add cypress cache and skip on relevant jobs

* ci: fix cache for cypress binary

* ci: try to fix cypress binary cache on e2e job
2019-06-11 15:12:40 -05:00
dependabot-preview[bot]
67a884cc48 Build(deps-dev): bump node-mocks-http from 1.7.5 to 1.7.6 (#3554)
Bumps [node-mocks-http](https://github.com/howardabrams/node-mocks-http) from 1.7.5 to 1.7.6.
- [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.7.5...v1.7.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-11 21:16:01 +02:00
dependabot-preview[bot]
544d7d3648 Build(deps-dev): bump gatsby-plugin-catch-links from 2.0.13 to 2.0.15 (#3550)
Bumps [gatsby-plugin-catch-links](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-catch-links) from 2.0.13 to 2.0.15.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-catch-links/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-catch-links@2.0.15/packages/gatsby-plugin-catch-links)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-11 06:01:17 -05:00
dependabot-preview[bot]
e8a00e5f93 Build(deps-dev): bump mocha-junit-reporter from 1.22.0 to 1.23.0 (#3551)
Bumps [mocha-junit-reporter](https://github.com/michaelleeallen/mocha-junit-reporter) from 1.22.0 to 1.23.0.
- [Release notes](https://github.com/michaelleeallen/mocha-junit-reporter/releases)
- [Commits](https://github.com/michaelleeallen/mocha-junit-reporter/compare/v1.22.0...v1.23.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-10 19:34:07 -05:00
dependabot-preview[bot]
1f77b7836f Build(deps): bump simple-icons from 1.9.27 to 1.9.28 (#3549)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.27 to 1.9.28.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-10 19:08:51 -05:00
dependabot-preview[bot]
b832c27956 Build(deps-dev): bump styled-components from 4.2.0 to 4.3.1 (#3548)
Bumps [styled-components](https://github.com/styled-components/styled-components) from 4.2.0 to 4.3.1.
- [Release notes](https://github.com/styled-components/styled-components/releases)
- [Changelog](https://github.com/styled-components/styled-components/blob/master/CHANGELOG.md)
- [Commits](https://github.com/styled-components/styled-components/compare/styled-components@4.2.0...v4.3.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-10 17:47:41 -05:00
dependabot-preview[bot]
3a90e99902 Build(deps-dev): bump fetch-ponyfill from 6.0.0 to 6.1.0 (#3546)
Bumps [fetch-ponyfill](https://github.com/qubyte/fetch-ponyfill) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/qubyte/fetch-ponyfill/releases)
- [Changelog](https://github.com/qubyte/fetch-ponyfill/blob/master/HISTORY.md)
- [Commits](https://github.com/qubyte/fetch-ponyfill/compare/v6.0.0...v6.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-10 17:25:37 -05:00
dependabot-preview[bot]
0ecaead3fb Build(deps): bump fsos from 1.1.3 to 1.1.6 (#3547)
Bumps [fsos](https://github.com/espadrine/fsos) from 1.1.3 to 1.1.6.
- [Release notes](https://github.com/espadrine/fsos/releases)
- [Commits](https://github.com/espadrine/fsos/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-06-10 19:51:39 +01:00
Caleb Cartwright
c80cc0c4fd tests: fix EclipseMarketplaceLicense test (#3542) 2019-06-10 09:54:10 -05:00
Caleb Cartwright
15b8e62739 chore: fix hapi import in jitpackdownloads (#3543) 2019-06-10 09:39:25 -05:00
Caleb Cartwright
3fec21a028 restore [JitpackDownloads] badge (#3533)
* feat: restore JitpackDownloads badge

* chore: use interval name in jitpackdownloads
2019-06-09 16:44:44 -05:00
Pierre-Yves B
e9f24af878 EPL-2.0 license (#3539) 2019-06-09 18:14:01 +01:00
严尚君
c2c8fb6d7f add gitee (#3531)
add gitee
2019-06-08 12:45:36 -05:00
Axel Huebl
6cdb2a6b98 Spack Package Manager: Latest Version (#3536)
Add support for the Spack package manager (https://spack.io).
Spack is a modern multi-language, multi-variant software package
manager in high-performance computing (HPC).
2019-06-08 17:12:50 +01:00
dependabot[bot]
317a11ec0a Build(deps): bump nwmatcher from 1.4.2 to 1.4.4 (#3537)
Bumps [nwmatcher](https://github.com/dperini/nwmatcher) from 1.4.2 to 1.4.4.
- [Release notes](https://github.com/dperini/nwmatcher/releases)
- [Commits](https://github.com/dperini/nwmatcher/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2019-06-07 18:30:00 -05:00
dependabot-preview[bot]
e1029467a1 Build(deps-dev): bump prettier from 1.16.4 to 1.17.1 (#3526)
Bumps [prettier](https://github.com/prettier/prettier) from 1.16.4 to 1.17.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.16.4...1.17.1)
2019-06-06 17:16:56 -05:00
Corebreaker
76e8d8e05f Allow nulls for boolean fields on Libraries.io APIs (#3530) 2019-06-05 18:14:23 -05:00
dependabot-preview[bot]
c2f7ca9daa Build(deps-dev): bump react-select from 2.4.3 to 3.0.4 (#3525)
Bumps [react-select](https://github.com/JedWatson/react-select) from 2.4.3 to 3.0.4.
- [Release notes](https://github.com/JedWatson/react-select/releases)
- [Changelog](https://github.com/JedWatson/react-select/blob/master/.sweet-changelogs.js)
- [Commits](https://github.com/JedWatson/react-select/commits)
2019-06-04 18:35:06 -05:00
dependabot-preview[bot]
71020e32be Build(deps-dev): bump walkdir from 0.3.2 to 0.4.0 (#3524)
Bumps [walkdir](https://github.com/soldair/node-walkdir) from 0.3.2 to 0.4.0.
- [Release notes](https://github.com/soldair/node-walkdir/releases)
- [Changelog](https://github.com/soldair/node-walkdir/blob/master/CHANGELOG.md)
- [Commits](https://github.com/soldair/node-walkdir/compare/v0.3.2...v0.4.0)
2019-06-04 18:16:10 -05:00
dependabot-preview[bot]
4d1df82042 Build(deps-dev): bump start-server-and-test from 1.9.0 to 1.9.1 (#3521)
Bumps [start-server-and-test](https://github.com/bahmutov/start-server-and-test) from 1.9.0 to 1.9.1.
- [Release notes](https://github.com/bahmutov/start-server-and-test/releases)
- [Commits](https://github.com/bahmutov/start-server-and-test/compare/v1.9.0...v1.9.1)
2019-06-04 18:05:58 -05:00
dependabot-preview[bot]
723a588137 Build(deps-dev): bump gatsby-plugin-page-creator from 2.0.12 to 2.0.13 (#3523)
Bumps [gatsby-plugin-page-creator](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-page-creator) from 2.0.12 to 2.0.13.
- [Release notes](https://github.com/gatsbyjs/gatsby/releases)
- [Changelog](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-plugin-page-creator/CHANGELOG.md)
- [Commits](https://github.com/gatsbyjs/gatsby/commits/gatsby-plugin-page-creator@2.0.13/packages/gatsby-plugin-page-creator)
2019-06-04 17:52:40 -05:00
dependabot-preview[bot]
0204f4c12b Build(deps-dev): bump danger from 7.1.2 to 7.1.4 (#3522)
Bumps [danger](https://github.com/danger/danger-js) from 7.1.2 to 7.1.4.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/7.1.2...7.1.4)
2019-06-04 17:29:01 -05:00
dependabot-preview[bot]
591e5bf755 Build(deps-dev): bump is-svg from 4.1.0 to 4.2.0 (#3519)
Bumps [is-svg](https://github.com/sindresorhus/is-svg) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/sindresorhus/is-svg/releases)
- [Commits](https://github.com/sindresorhus/is-svg/compare/v4.1.0...v4.2.0)
2019-06-03 22:28:07 +01:00
dependabot-preview[bot]
d86a1f0895 Build(deps): bump semver from 6.0.0 to 6.1.1 (#3520)
Bumps [semver](https://github.com/npm/node-semver) from 6.0.0 to 6.1.1.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v6.0.0...v6.1.1)
2019-06-03 22:16:06 +01:00
dependabot-preview[bot]
283744ac0d Build(deps): bump jsonpath from 1.0.1 to 1.0.2 (#3527)
Bumps [jsonpath](https://github.com/dchester/jsonpath) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/dchester/jsonpath/releases)
- [Commits](https://github.com/dchester/jsonpath/commits/1.0.2)
2019-06-03 22:04:36 +01:00
dependabot-preview[bot]
3239d55ea4 Build(deps): bump simple-icons from 1.9.26 to 1.9.27 (#3528)
Bumps [simple-icons](https://github.com/simple-icons/simple-icons) from 1.9.26 to 1.9.27.
- [Release notes](https://github.com/simple-icons/simple-icons/releases)
- [Commits](https://github.com/simple-icons/simple-icons/commits)
2019-06-03 21:48:15 +01:00
chris48s
8621fe42d7 Upgrade Joi (#3505)
* upgrade joi
* find & replace ALL THE THINGS
* update related deps
2019-06-02 21:59:55 +01:00
Caleb Cartwright
b95811ba40 fix: modal scroll bug (#3517) 2019-06-02 11:42:16 -05:00
Caleb Cartwright
054b2eb5ba fix: circle token query param bug (#3516) 2019-06-02 12:31:59 -04:00
James Cahill
a2641ac5e3 Add [Mastodon] service (#3508)
* add mastodon follow service

* Use nonNegativeInteger for followers_count

* Add documentation
2019-05-31 11:38:36 -05:00
Mackenzie Miller
ca49e522b3 Make dropdown visible when it overflows modal content (#3510)
Resolves #2806
2019-05-30 21:51:06 -04:00
chris48s
98f380b254 improve logo escaping (#3511)
* escape logo in make-badge

* 2.2.1 release notes

* tighten up validation of logo param
2019-05-30 18:28:37 +01:00
chris48s
829971f0ef Fix BadgeFactory.create() docblock (#3506)
* fix docblock

* add a reminder in make-badge.js
2019-05-30 12:28:17 +01:00
chris48s
bfe0bde83d switch [powershellgallery] platform example (#3504)
The example we were previously using
(Az.Storage) now renders

platform | not specified

This replaces the example with a
package that gives us a valid result
2019-05-29 21:21:35 +01:00
Marcin Mielnicki
9008c4ef0f Show a badge pattern instead of a badge url (#3438)
* Show patterns instead of real paths

* realBadge property instead of preview.buildFromExample

* E2e test for displaying a badge

* Check bagde url in badge wrapper

* expectBadgeExample helper function

* Remove a hostname from badge url

* Simpler Cypress assertions

* realBadge -> isBadgeSuggestion

* Do not show regexp in patterns
2019-05-29 21:17:27 +02:00
chris48s
f50fcac107 fix 'failing service test' template (#3503) 2019-05-29 16:30:16 +01:00
703 changed files with 21089 additions and 12291 deletions

View File

@@ -13,6 +13,10 @@ main_steps: &main_steps
- run:
name: Install dependencies
command: npm ci
environment:
# https://docs.cypress.io/guides/getting-started/installing-cypress.html#Skipping-installation
# We don't need to install the Cypress binary in jobs that aren't actually running Cypress.
CYPRESS_INSTALL_BINARY: 0
- save_cache:
paths:
@@ -61,6 +65,8 @@ integration_steps: &integration_steps
- run:
name: Install dependencies
command: npm ci
environment:
CYPRESS_INSTALL_BINARY: 0
- run:
name: Integration tests
@@ -86,6 +92,8 @@ services_steps: &services_steps
- run:
name: Install dependencies
command: npm ci
environment:
CYPRESS_INSTALL_BINARY: 0
- run:
name: Identify services tagged in the PR title
@@ -96,7 +104,7 @@ services_steps: &services_steps
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/services/results.xml
command: npm run test:services:pr:run
command: RETRY_COUNT=3 npm run test:services:pr:run
- store_test_results:
path: junit
@@ -133,6 +141,8 @@ package_steps: &package_steps
nvm use v12
npm install -g npm
npm ci
environment:
CYPRESS_INSTALL_BINARY: 0
# Run the package tests on each currently supported node version. See:
# https://github.com/badges/shields/blob/master/gh-badges/README.md#node-version-support
@@ -153,14 +163,6 @@ package_steps: &package_steps
NODE_VERSION: v10
name: Run package tests on Node 10
- run:
<<: *run_package_tests
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/gh-badges/v11/results.xml
NODE_VERSION: v11
name: Run package tests on Node 11
- run:
<<: *run_package_tests
environment:
@@ -188,6 +190,8 @@ jobs:
- run:
name: Install dependencies
command: npm ci
environment:
CYPRESS_INSTALL_BINARY: 0
- save_cache:
paths:
@@ -235,6 +239,8 @@ jobs:
- run:
name: Install dependencies
command: npm ci
environment:
CYPRESS_INSTALL_BINARY: 0
- run:
name: Danger
@@ -259,16 +265,23 @@ jobs:
- run:
name: Install dependencies
command: npm ci
environment:
CYPRESS_INSTALL_BINARY: 0
- run:
name: Prepare frontend tests
command: npm run defs && npm run features
- run:
name: Check types
command: npm run check-types:frontend
- run:
name: Frontend unit tests
environment:
mocha_reporter: mocha-junit-reporter
MOCHA_FILE: junit/frontend/results.xml
when: always
command: npm run test:frontend
- store_test_results:
@@ -303,11 +316,17 @@ jobs:
- checkout
- restore_cache:
name: Restore node_modules
keys:
- v2-dependencies-{{ checksum "package-lock.json" }}
# https://github.com/badges/shields/issues/1937
- v2-dependencies-
- restore_cache:
name: Restore Cypress binary
keys:
- v2-cypress-dependencies-{{ checksum "package-lock.json" }}
- run:
name: Install dependencies
command: npm ci
@@ -332,6 +351,13 @@ jobs:
- store_artifacts:
path: cypress/screenshots
- save_cache:
name: Cache Cypress binary
paths:
# https://docs.cypress.io/guides/getting-started/installing-cypress.html#Binary-cache
- ~/.cache/Cypress
key: v2-cypress-dependencies-{{ checksum "package-lock.json" }}
workflows:
version: 2

View File

@@ -1,3 +1,4 @@
/api-docs/
/build
/coverage
/__snapshots__

View File

@@ -1,28 +0,0 @@
env:
browser: true
plugins:
- import
- react-hooks
parser: 'babel-eslint'
parserOptions:
sourceType: 'module'
extends:
- 'standard-jsx'
- 'standard-react'
- './.eslintrc.yml'
settings:
react:
version: '16.4'
rules:
no-console: 'error'
import/extensions: ['error', 'never', { 'json': 'always', 'yml': 'always' }]
react/jsx-sort-props: 'error'
react-hooks/rules-of-hooks: 'error'
react-hooks/exhaustive-deps: 'error'

View File

@@ -1,21 +1,72 @@
extends:
- standard
- prettier
env:
node: true
mocha: true
- standard-jsx
- standard-react
- plugin:@typescript-eslint/recommended
- prettier/@typescript-eslint
- prettier/standard
- prettier/react
- eslint:recommended
parserOptions:
# Override eslint-config-standard, which incorrectly sets this to "module",
# though that setting is only for ES6 modules, not CommonJS modules.
sourceType: 'script'
settings:
react:
version: '16.8'
plugins:
- chai-friendly
- jsdoc
- mocha
- no-extension-in-require
- sort-class-members
- import
- react-hooks
- promise
overrides:
# For simplicity's sake, when possible prefer to add rules to the top-level
# list of rules, even if they only apply to certain files. That way the
# rules listed here are only ones which conflict.
- files:
- gatsby-browser.js
- '**/*.js'
- '!frontend/**/*.js'
env:
node: true
es6: true
rules:
no-console: 'off'
'@typescript-eslint/no-var-requires': off
- files:
- '**/*.@(ts|tsx)'
parserOptions:
sourceType: 'module'
parser: '@typescript-eslint/parser'
rules:
# Argh.
'@typescript-eslint/explicit-function-return-type': 'off'
'@typescript-eslint/no-object-literal-type-assertion': 'off'
- files:
- core/**/*.ts
parserOptions:
sourceType: 'module'
parser: '@typescript-eslint/parser'
- files:
- gatsby-browser.js
- 'frontend/**/*.@(js|ts|tsx)'
parserOptions:
sourceType: 'module'
env:
browser: true
rules:
import/extensions:
['error', 'never', { 'json': 'always', 'yml': 'always' }]
- files:
- 'core/base-service/**/*.js'
- 'services/**/*.js'
@@ -30,6 +81,7 @@ overrides:
'category',
'isDeprecated',
'route',
'auth',
'examples',
'_cacheLength',
'defaultBadgeData',
@@ -42,24 +94,31 @@ overrides:
},
]
plugins:
- mocha
- no-extension-in-require
- chai-friendly
- sort-class-members
- files:
- '**/*.spec.@(js|ts|tsx)'
- '**/*.integration.js'
- '**/test-helpers.js'
- 'core/service-test-runner/**/*.js'
env:
mocha: true
rules:
mocha/no-exclusive-tests: 'error'
mocha/no-mocha-arrows: 'error'
mocha/prefer-arrow-callback: 'error'
rules:
# Disable some rules from eslint:recommended.
no-console: 'off'
no-empty: ['error', { 'allowEmptyCatch': true }]
# Allow unused parameters. In callbacks, removing them seems to obscure
# what the functions are doing.
no-unused-vars: ['error', { 'args': 'none' }]
'@typescript-eslint/no-unused-vars': ['error', { 'args': 'none' }]
no-unused-vars: off
'@typescript-eslint/no-var-requires': error
# These should be disabled by eslint-config-prettier, but are not.
spaced-comment: 'off'
standard/object-curly-even-spacing: 'off'
one-var: 'off'
no-extra-semi: 'off'
# Shields additions.
no-var: 'error'
@@ -74,11 +133,38 @@ rules:
new-cap: ['error', { 'capIsNew': true }]
import/order: ['error', { 'newlines-between': 'never' }]
# Mocha-related.
mocha/no-exclusive-tests: 'error'
mocha/no-mocha-arrows: 'error'
mocha/prefer-arrow-callback: 'error'
# Chai friendly.
no-unused-expressions: 'off'
chai-friendly/no-unused-expressions: 'error'
# jsdoc plugin:
# don't require every class/function to have a docblock
jsdoc/require-jsdoc: 'off'
# allow Joi as an undefined type
jsdoc/no-undefined-types: ['error', { definedTypes: ['Joi'] }]
# all the other reccomended rules as errors (not warnings)
jsdoc/check-alignment: 'error'
jsdoc/check-param-names: 'error'
jsdoc/check-tag-names: 'error'
jsdoc/check-types: 'error'
jsdoc/implements-on-classes: 'error'
jsdoc/newline-after-description: 'error'
jsdoc/require-param: 'error'
jsdoc/require-param-description: 'error'
jsdoc/require-param-name: 'error'
jsdoc/require-param-type: 'error'
jsdoc/require-returns: 'error'
jsdoc/require-returns-check: 'error'
jsdoc/require-returns-description: 'error'
jsdoc/require-returns-type: 'error'
jsdoc/valid-types: 'error'
# Disable some from TypeScript.
'@typescript-eslint/camelcase': off
react/jsx-sort-props: 'error'
react-hooks/rules-of-hooks: 'error'
react-hooks/exhaustive-deps: 'error'
jsx-quotes: ['error', 'prefer-double']

View File

@@ -1,6 +1,7 @@
---
name: 🐛 Bug Report
about: Report errors and problems
labels: 'question'
---
Are you experiencing an issue with...

View File

@@ -1,6 +1,7 @@
---
name: :green_heart: Failing service test
name: 💚 Failing service test
about: Note failing service tests
labels: 'keep-service-tests-green'
---
:clock11: **When did the problem start?**

View File

@@ -1,6 +1,7 @@
---
name: 💡 Badge Request
about: Ideas for new badges
labels: 'service-badge'
---
:clipboard: **Description**

View File

@@ -1,6 +1,7 @@
---
name: ❓ Support Question
about: Ask a question about shields.io
labels: 'question'
---
:question: **Question**

3
.gitignore vendored
View File

@@ -110,3 +110,6 @@ service-definitions.yml
# Cypress
/cypress/videos/
/cypress/screenshots/
# Rendered API docs
/api-docs/

View File

@@ -1,5 +1,27 @@
ports:
- port: 8080
onOpen: open-preview
tasks:
- init: npm ci && npm run build
command: node server 8080 0.0.0.0
github:
prebuilds:
# enable for the master/default branch (defaults to true)
master: true
# enable for all branches in this repo (defaults to false)
branches: false
# enable for pull requests coming from this repo (defaults to true)
pullRequests: true
# enable for pull requests coming from forks (defaults to false)
pullRequestsFromForks: true
# add a check to pull requests (defaults to true)
addCheck: true
# add a "Review in Gitpod" button as a comment to pull requests (defaults to false)
addComment: false
# add a "Review in Gitpod" button to the pull request's description (defaults to false)
addBadge: false
# add a label once the prebuild is ready to pull requests (defaults to false)
addLabel: false
vscode:
extensions:
- esbenp.prettier-vscode@1.7.0:EbyqFvwe32qQBptkOgfQpQ==

View File

@@ -9,9 +9,11 @@
"**/test-helpers.js",
"**/*-test-helpers.js",
"**/*-fixtures.js",
"**/mocha-*.js",
"dangerfile.js",
"gatsby-*.js",
"core/service-test-runner",
"core/got-test-client.js",
"services/**/*.tester.js",
"services/test-validators.js",
"services/tester.js",

View File

@@ -3,6 +3,7 @@ package-lock.json
/__snapshots__
/.next
/.cache
/api-docs
/build
/public
/coverage

View File

@@ -24,10 +24,20 @@ maybe you'd like to open a pull request to address one of them:
You can help by improving the project's usage and developer instructions.
Tutorials are in [/doc](https://github.com/badges/shields/tree/master/doc):
- When you read the documentation, you can fix mistakes and add your own thoughts.
- When your pull request follows the documentation but the practice changed,
consider pointing this out and change the documentation for the next person.
API documentation is at [contributing.shields.io](https://contributing.shields.io/):
- This documentation is generated by annotating the code with
[JSDoc](https://jsdoc.app/about-getting-started.html) comments.
[Example](https://github.com/badges/shields/blob/b3be4d94d5ef570b8daccfd088c343a958988843/core/base-service/base-json.js#L26-L41)
- Adding a JSDoc comment to some existing code is a great first contribution
and a good way to familiarize yourself with the codebase
### Helping others
You can help with code review, which reduces bugs, and over time has a
@@ -95,12 +105,11 @@ There are three places to get help:
## Badge URLs
- The format of new badges should be of the form
`/SERVICE/NOUN/PARAMETERS/QUALIFIERS.format`. For instance,
`/gitter/room/nwjs/nw.js.svg`. The vendor is gitter, the
badge is for rooms, the parameter is nwjs/nw.js, and the format is svg.
- For services which require a hostname, the badge should be of the form
`/SERVICE/SCHEME/HOST/NOUN/PARAMETERS/QUALIFIERS.format`. For instance,
`/discourse/https/discourse.example.com/topics.svg`.
`/SERVICE/NOUN/PARAMETERS/QUALIFIERS`. For instance,
`/gitter/room/nwjs/nw.js`. The vendor is gitter, the
badge is for rooms, and the parameter is nwjs/nw.js.
- Services which require a url/hostname parameter should use a query parameter to accept that value. For instance,
`/discourse/topics?server=https://meta.discourse.org`.
## Coding guidelines

View File

@@ -1,7 +1,5 @@
FROM node:8-alpine
RUN apk add --no-cache gettext imagemagick librsvg git
RUN mkdir -p /usr/src/app
RUN mkdir /usr/src/app/private
WORKDIR /usr/src/app
@@ -10,8 +8,8 @@ COPY package.json package-lock.json /usr/src/app/
# Without the gh-badges package.json and CLI script in place, `npm ci` will fail.
COPY gh-badges /usr/src/app/gh-badges/
# We need dev deps to build the front end.
RUN NODE_ENV=development npm ci
# We need dev deps to build the front end. We don't need Cypress, though.
RUN NODE_ENV=development CYPRESS_INSTALL_BINARY=0 npm ci
COPY . /usr/src/app
RUN npm run build

View File

@@ -1,35 +1,35 @@
<p align="center">
<img src="./frontend/images/logo.svg"
<img src="https://raw.githubusercontent.com/badges/shields/master/frontend/images/logo.svg?sanitize=true"
height="130">
</p>
<p align="center">
<a href="https://github.com/badges/shields/graphs/contributors" alt="Contributors">
<img src="https://img.shields.io/github/contributors/badges/shields.svg" /></a>
<img src="https://img.shields.io/github/contributors/badges/shields" /></a>
<a href="#backers" alt="Backers on Open Collective">
<img src="https://img.shields.io/opencollective/backers/shields.svg" /></a>
<img src="https://img.shields.io/opencollective/backers/shields" /></a>
<a href="#sponsors" alt="Sponsors on Open Collective">
<img src="https://img.shields.io/opencollective/sponsors/shields.svg" /></a>
<img src="https://img.shields.io/opencollective/sponsors/shields" /></a>
<a href="https://github.com/badges/shields/pulse" alt="Activity">
<img src="https://img.shields.io/github/commit-activity/m/badges/shields.svg" /></a>
<img src="https://img.shields.io/github/commit-activity/m/badges/shields" /></a>
<a href="https://circleci.com/gh/badges/shields/tree/master">
<img src="https://img.shields.io/circleci/project/github/badges/shields/master.svg" alt="build status"></a>
<img src="https://img.shields.io/circleci/project/github/badges/shields/master" alt="build status"></a>
<a href="https://circleci.com/gh/badges/daily-tests">
<img src="https://img.shields.io/circleci/project/github/badges/daily-tests.svg?label=service%20tests"
<img src="https://img.shields.io/circleci/project/github/badges/daily-tests?label=service%20tests"
alt="service-test status"></a>
<a href="https://coveralls.io/github/badges/shields">
<img src="https://img.shields.io/coveralls/github/badges/shields.svg"
<img src="https://img.shields.io/coveralls/github/badges/shields"
alt="coverage"></a>
<a href="https://lgtm.com/projects/g/badges/shields/alerts/">
<img src="https://img.shields.io/lgtm/alerts/g/badges/shields.svg"
<img src="https://img.shields.io/lgtm/alerts/g/badges/shields"
alt="Total alerts"/></a>
<a href="https://github.com/badges/shields/compare/gh-pages...master">
<img src="https://img.shields.io/github/commits-since/badges/shields/gh-pages.svg?label=commits%20to%20be%20deployed"
<img src="https://img.shields.io/github/commits-since/badges/shields/gh-pages?label=commits%20to%20be%20deployed"
alt="commits to be deployed"></a>
<a href="https://discord.gg/HjJCwm5">
<img src="https://img.shields.io/discord/308323056592486420.svg?logo=discord"
<img src="https://img.shields.io/discord/308323056592486420?logo=discord"
alt="chat on Discord"></a>
<a href="https://twitter.com/intent/follow?screen_name=shields_io">
<img src="https://img.shields.io/twitter/follow/shields_io.svg?style=social&logo=twitter"
<img src="https://img.shields.io/twitter/follow/shields_io?style=social&logo=twitter"
alt="follow on Twitter"></a>
</p>
@@ -56,19 +56,19 @@ This repo hosts:
## Examples
- code coverage percentage: ![coverage](https://img.shields.io/badge/coverage-80%25-yellowgreen.svg?cacheSeconds=2592000)
- stable release version: ![version](https://img.shields.io/badge/version-1.2.3-blue.svg?cacheSeconds=2592000)
- package manager release: ![gem](https://img.shields.io/badge/gem-2.2.0-blue.svg?cacheSeconds=2592000)
- status of third-party dependencies: ![dependencies](https://img.shields.io/badge/dependencies-out%20of%20date-orange.svg?cacheSeconds=2592000)
- static code analysis grade: ![codacy](https://img.shields.io/badge/codacy-B-green.svg?cacheSeconds=2592000)
- [SemVer](https://semver.org/) version observance: ![semver](https://img.shields.io/badge/semver-2.0.0-blue.svg?cacheSeconds=2592000)
- amount of [Liberapay](https://liberapay.com/) donations per week: ![receives](https://img.shields.io/badge/receives-2.00%20USD%2Fweek-yellow.svg?cacheSeconds=2592000)
- Python package downloads: ![downloads](https://img.shields.io/badge/downloads-13k%2Fmonth-brightgreen.svg?cacheSeconds=2592000)
- Chrome Web Store extension rating: ![rating](https://img.shields.io/badge/rating-★★★★☆-brightgreen.svg?cacheSeconds=2592000)
- [Uptime Robot](https://uptimerobot.com) percentage: ![uptime](https://img.shields.io/badge/uptime-100%25-brightgreen.svg?cacheSeconds=2592000)
- code coverage percentage: ![coverage](https://img.shields.io/badge/coverage-80%25-yellowgreen)
- stable release version: ![version](https://img.shields.io/badge/version-1.2.3-blue)
- package manager release: ![gem](https://img.shields.io/badge/gem-2.2.0-blue)
- status of third-party dependencies: ![dependencies](https://img.shields.io/badge/dependencies-out%20of%20date-orange)
- static code analysis grade: ![codacy](https://img.shields.io/badge/codacy-B-green)
- [SemVer](https://semver.org/) version observance: ![semver](https://img.shields.io/badge/semver-2.0.0-blue)
- amount of [Liberapay](https://liberapay.com/) donations per week: ![receives](https://img.shields.io/badge/receives-2.00%20USD%2Fweek-yellow)
- Python package downloads: ![downloads](https://img.shields.io/badge/downloads-13k%2Fmonth-brightgreen)
- Chrome Web Store extension rating: ![rating](https://img.shields.io/badge/rating-★★★★☆-brightgreen)
- [Uptime Robot](https://uptimerobot.com) percentage: ![uptime](https://img.shields.io/badge/uptime-100%25-brightgreen)
[Make your own badges!][custom badges]
(Quick example: `https://img.shields.io/badge/left-right-f39f37.svg`)
(Quick example: `https://img.shields.io/badge/left-right-f39f37`)
Browse a [complete list of badges][shields.io].
@@ -84,7 +84,8 @@ When adding or changing a service [please add tests][service-tests].
This project has quite a backlog of suggestions! If you're new to the project,
maybe you'd like to open a pull request to address one of them:
[![GitHub issues by-label](https://img.shields.io/github/issues/badges/shields/good%20first%20issue.svg)](https://github.com/badges/shields/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
[![Hacktoberfest](https://img.shields.io/github/hacktoberfest/2019/badges/shields)](https://github.com/badges/shields/issues?q=is%3Aopen+is%3Aissue+label%3Ahacktoberfest)
[![GitHub issues by-label](https://img.shields.io/github/issues/badges/shields/good%20first%20issue)](https://github.com/badges/shields/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
You can read a [tutorial on how to add a badge][tutorial].
@@ -107,14 +108,14 @@ server (`gatsby dev`) should also automatically reload. However the badge
definitions are built only before the server first starts. To regenerate those,
either run `npm run defs` or manually restart the server.
To debug a badge from the command line, run `npm run badge -- /npm/v/nock.svg`.
To debug a badge from the command line, run `npm run badge -- /npm/v/nock`.
It also works with full URLs like
`npm run badge -- https://img.shields.io/npm/v/nock.svg`.
`npm run badge -- https://img.shields.io/npm/v/nock`.
Use `npm run debug:server` to start server in debug mode.
[This recipe][nodemon debug] shows how to debug Node.js application in [VS Code][].
Shields has experimental support for [Gitpod Beta][gitpod], a pre-configured development
Shields has experimental support for [Gitpod][gitpod], a pre-configured development
environment that runs in your browser. To use Gitpod, click the button below and
sign in with GitHub. Gitpod also offers a browser add-on, though it is not required.
Please report any Gitpod bugs, questions, or suggestions in issue

View File

@@ -6,6 +6,16 @@
"repository": "https://github.com/badges/shields",
"logo": "http://shields.io/favicon.png",
"env": {
"CYPRESS_INSTALL_BINARY": {
"description": "Disable the cypress binary installation",
"value": "0",
"required": false
},
"HUSKY_SKIP_INSTALL": {
"description": "Skip the husky git hook setup",
"value": "1",
"required": false
},
"WHEELMAP_TOKEN": {
"description": "Configure the token to be used for the Wheelmap service.",
"required": false
@@ -13,6 +23,14 @@
"GH_TOKEN": {
"description": "Configure the token to be used for the GitHub services.",
"required": false
},
"TWITCH_CLIENT_ID": {
"description": "Configure the client id to be used for the Twitch service.",
"required": false
},
"TWITCH_CLIENT_SECRET": {
"description": "Configure the client secret to be used for the Twitch service.",
"required": false
}
},
"formation": {

View File

@@ -14,6 +14,8 @@ public:
redirectUri: 'REDIRECT_URI'
rasterUrl: 'RASTER_URL'
cors:
allowedOrigin:
__name: 'ALLOWED_ORIGIN'
@@ -21,7 +23,6 @@ public:
persistence:
dir: 'PERSISTENCE_DIR'
redisUrl: 'REDIS_URL'
services:
github:
@@ -56,9 +57,12 @@ private:
nexus_user: 'NEXUS_USER'
nexus_pass: 'NEXUS_PASS'
npm_token: 'NPM_TOKEN'
redis_url: 'REDIS_URL'
sentry_dsn: 'SENTRY_DSN'
shields_secret: 'SHIELDS_SECRET'
sl_insight_userUuid: 'SL_INSIGHT_USER_UUID'
sl_insight_apiToken: 'SL_INSIGHT_API_TOKEN'
sonarqube_token: 'SONARQUBE_TOKEN'
twitch_client_id: 'TWITCH_CLIENT_ID'
twitch_client_secret: 'TWITCH_CLIENT_SECRET'
wheelmap_token: 'WHEELMAP_TOKEN'

View File

@@ -7,4 +7,6 @@ private:
shields_secret: ...
sl_insight_userUuid: ...
sl_insight_apiToken: ...
twitch_client_id: ...
twitch_client_secret: ...
wheelmap_token: ...

View File

@@ -5,4 +5,6 @@ private:
# you can also set these values through environment variables, which may be
# preferable for self hosting.
gh_token: '...'
twitch_client_id: '...'
twitch_client_secret: '...'
wheelmap_token: '...'

View File

@@ -11,6 +11,8 @@ public:
redirectUrl: 'https://shields.io/'
rasterUrl: 'https://raster.shields.io'
private:
# These are not really private; they should be moved to `public`.
shields_ips: ['192.99.59.72', '51.254.114.150', '149.56.96.133']

View File

@@ -5,6 +5,8 @@ public:
rateLimit: false
redirectUrl: 'http://badge-server.example.com'
redirectUrl: 'http://frontend.example.test'
rasterUrl: 'http://raster.example.test'
handleInternalErrors: false

108
core/badge-urls/make-badge-url.d.ts vendored Normal file
View File

@@ -0,0 +1,108 @@
export function badgeUrlFromPath({
baseUrl,
path,
queryParams,
style,
format,
longCache,
}: {
baseUrl?: string
path: string
queryParams: { [k: string]: string | number | boolean }
style?: string
format?: string
longCache?: boolean
}): string
export function badgeUrlFromPattern({
baseUrl,
pattern,
namedParams,
queryParams,
style,
format,
longCache,
}: {
baseUrl?: string
pattern: string
namedParams: { [k: string]: string }
queryParams: { [k: string]: string | number | boolean }
style?: string
format?: string
longCache?: boolean
}): string
export function encodeField(s: string): string
export function staticBadgeUrl({
baseUrl,
label,
message,
color,
style,
namedLogo,
format,
}: {
baseUrl?: string
label: string
message: string
color?: string
style?: string
namedLogo?: string
format?: string
}): string
export function queryStringStaticBadgeUrl({
baseUrl,
label,
message,
color,
labelColor,
style,
namedLogo,
logoColor,
logoWidth,
logoPosition,
format,
}: {
baseUrl?: string
label: string
message: string
color?: string
labelColor?: string
style?: string
namedLogo?: string
logoColor?: string
logoWidth?: number
logoPosition?: number
format?: string
}): string
export function dynamicBadgeUrl({
baseUrl,
datatype,
label,
dataUrl,
query,
prefix,
suffix,
color,
style,
format,
}: {
baseUrl?: string
datatype: string
label: string
dataUrl: string
query: string
prefix: string
suffix: string
color?: string
style?: string
format?: string
}): string
export function rasterRedirectUrl(
{ rasterUrl }: { rasterUrl: string },
badgeUrl: string
): string

View File

@@ -1,5 +1,6 @@
'use strict'
const { URL } = require('url')
const queryString = require('query-string')
const pathToRegexp = require('path-to-regexp')
@@ -8,7 +9,7 @@ function badgeUrlFromPath({
path,
queryParams,
style,
format = 'svg',
format = '',
longCache = false,
}) {
const outExt = format.length ? `.${format}` : ''
@@ -29,7 +30,7 @@ function badgeUrlFromPattern({
namedParams,
queryParams,
style,
format = 'svg',
format = '',
longCache = false,
}) {
const toPath = pathToRegexp.compile(pattern, {
@@ -60,15 +61,16 @@ function staticBadgeUrl({
color = 'lightgray',
style,
namedLogo,
format = 'svg',
format = '',
}) {
const path = [label, message, color].map(encodeField).join('-')
const outQueryString = queryString.stringify({
style,
logo: namedLogo,
})
const outExt = format.length ? `.${format}` : ''
const suffix = outQueryString ? `?${outQueryString}` : ''
return `${baseUrl}/badge/${path}.${format}${suffix}`
return `${baseUrl}/badge/${path}${outExt}${suffix}`
}
function queryStringStaticBadgeUrl({
@@ -82,7 +84,7 @@ function queryStringStaticBadgeUrl({
logoColor,
logoWidth,
logoPosition,
format = 'svg',
format = '',
}) {
// schemaVersion could be a parameter if we iterate on it,
// for now it's hardcoded to the only supported version.
@@ -98,7 +100,8 @@ function queryStringStaticBadgeUrl({
logoWidth,
logoPosition,
})}`
return `${baseUrl}/static/v${schemaVersion}.${format}${suffix}`
const outExt = format.length ? `.${format}` : ''
return `${baseUrl}/static/v${schemaVersion}${outExt}${suffix}`
}
function dynamicBadgeUrl({
@@ -111,8 +114,10 @@ function dynamicBadgeUrl({
suffix,
color,
style,
format = 'svg',
format = '',
}) {
const outExt = format.length ? `.${format}` : ''
const queryParams = {
label,
url: dataUrl,
@@ -131,7 +136,16 @@ function dynamicBadgeUrl({
}
const outQueryString = queryString.stringify(queryParams)
return `${baseUrl}/badge/dynamic/${datatype}.${format}?${outQueryString}`
return `${baseUrl}/badge/dynamic/${datatype}${outExt}?${outQueryString}`
}
function rasterRedirectUrl({ rasterUrl }, badgeUrl) {
// Ensure we're always using the `rasterUrl` by using just the path from
// the request URL.
const { pathname, search } = new URL(badgeUrl, 'https://bogus.test')
const result = new URL(pathname, rasterUrl)
result.search = search
return result
}
module.exports = {
@@ -141,4 +155,5 @@ module.exports = {
staticBadgeUrl,
queryStringStaticBadgeUrl,
dynamicBadgeUrl,
rasterRedirectUrl,
}

View File

@@ -18,7 +18,7 @@ describe('Badge URL generation functions', function() {
style: 'flat-square',
longCache: true,
}).expect(
'http://example.com/npm/v/gh-badges.svg?cacheSeconds=2592000&style=flat-square'
'http://example.com/npm/v/gh-badges?cacheSeconds=2592000&style=flat-square'
)
})
@@ -30,7 +30,7 @@ describe('Badge URL generation functions', function() {
style: 'flat-square',
longCache: true,
}).expect(
'http://example.com/npm/v/gh-badges.svg?cacheSeconds=2592000&style=flat-square'
'http://example.com/npm/v/gh-badges?cacheSeconds=2592000&style=flat-square'
)
})
@@ -48,7 +48,7 @@ describe('Badge URL generation functions', function() {
message: 'bar',
color: 'blue',
style: 'flat-square',
}).expect('/badge/foo-bar-blue.svg?style=flat-square')
}).expect('/badge/foo-bar-blue?style=flat-square')
given({
label: 'foo',
message: 'bar',
@@ -62,24 +62,24 @@ describe('Badge URL generation functions', function() {
message: 'Привет Мир',
color: '#aabbcc',
}).expect(
'/badge/Hello%20World-%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%9C%D0%B8%D1%80-%23aabbcc.svg'
'/badge/Hello%20World-%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%9C%D0%B8%D1%80-%23aabbcc'
)
given({
label: '123-123',
message: 'abc-abc',
color: 'blue',
}).expect('/badge/123--123-abc--abc-blue.svg')
}).expect('/badge/123--123-abc--abc-blue')
given({
label: '123-123',
message: '',
color: 'blue',
style: 'social',
}).expect('/badge/123--123--blue.svg?style=social')
}).expect('/badge/123--123--blue?style=social')
given({
label: '',
message: 'blue',
color: 'blue',
}).expect('/badge/-blue-blue.svg')
}).expect('/badge/-blue-blue')
})
test(queryStringStaticBadgeUrl, () => {
@@ -89,9 +89,7 @@ describe('Badge URL generation functions', function() {
message: 'bar',
color: 'blue',
style: 'flat-square',
}).expect(
'/static/v1.svg?color=blue&label=foo&message=bar&style=flat-square'
)
}).expect('/static/v1?color=blue&label=foo&message=bar&style=flat-square')
given({
label: 'foo Bar',
message: 'bar Baz',
@@ -107,7 +105,7 @@ describe('Badge URL generation functions', function() {
message: 'Привет Мир',
color: '#aabbcc',
}).expect(
'/static/v1.svg?color=%23aabbcc&label=Hello%20World&message=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%9C%D0%B8%D1%80'
'/static/v1?color=%23aabbcc&label=Hello%20World&message=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%9C%D0%B8%D1%80'
)
})
@@ -125,7 +123,7 @@ describe('Badge URL generation functions', function() {
style: 'plastic',
}).expect(
[
'http://img.example.com/badge/dynamic/json.svg',
'http://img.example.com/badge/dynamic/json',
'?label=foo',
`&prefix=${encodeURIComponent(prefix)}`,
`&query=${encodeURIComponent(query)}`,
@@ -146,7 +144,7 @@ describe('Badge URL generation functions', function() {
style: 'plastic',
}).expect(
[
'http://img.example.com/badge/dynamic/json.svg',
'http://img.example.com/badge/dynamic/json',
'?color=blue',
'&label=foo',
`&query=${encodeURIComponent(query)}`,

View File

@@ -0,0 +1,55 @@
'use strict'
class AuthHelper {
constructor(
{
userKey,
passKey,
isRequired = false,
defaultToEmptyStringForUser = false,
},
privateConfig
) {
if (!userKey && !passKey) {
throw Error('Expected userKey or passKey to be set')
}
this._userKey = userKey
this._passKey = passKey
if (userKey) {
this.user = privateConfig[userKey]
} else {
this.user = defaultToEmptyStringForUser ? '' : undefined
}
this.pass = passKey ? privateConfig[passKey] : undefined
this.isRequired = isRequired
}
get isConfigured() {
return (
(this._userKey ? Boolean(this.user) : true) &&
(this._passKey ? Boolean(this.pass) : true)
)
}
get isValid() {
if (this.isRequired) {
return this.isConfigured
} else {
const configIsEmpty = !this.user && !this.pass
return this.isConfigured || configIsEmpty
}
}
get basicAuth() {
const { user, pass } = this
return this.isConfigured ? { user, pass } : undefined
}
get bearerAuthHeader() {
const { pass } = this
return this.isConfigured ? { Authorization: `Bearer ${pass}` } : undefined
}
}
module.exports = { AuthHelper }

View File

@@ -0,0 +1,103 @@
'use strict'
const { expect } = require('chai')
const { test, given, forCases } = require('sazerac')
const { AuthHelper } = require('./auth-helper')
describe('AuthHelper', function() {
it('throws without userKey or passKey', function() {
expect(() => new AuthHelper({}, {})).to.throw(
Error,
'Expected userKey or passKey to be set'
)
})
describe('isValid', function() {
function validate(config, privateConfig) {
return new AuthHelper(config, privateConfig).isValid
}
test(validate, () => {
forCases([
// Fully configured user + pass.
given(
{ userKey: 'myci_user', passKey: 'myci_pass', isRequired: true },
{ myci_user: 'admin', myci_pass: 'abc123' }
),
given(
{ userKey: 'myci_user', passKey: 'myci_pass' },
{ myci_user: 'admin', myci_pass: 'abc123' }
),
// Fully configured user or pass.
given(
{ userKey: 'myci_user', isRequired: true },
{ myci_user: 'admin' }
),
given(
{ passKey: 'myci_pass', isRequired: true },
{ myci_pass: 'abc123' }
),
given({ userKey: 'myci_user' }, { myci_user: 'admin' }),
given({ passKey: 'myci_pass' }, { myci_pass: 'abc123' }),
// Empty config.
given({ userKey: 'myci_user', passKey: 'myci_pass' }, {}),
given({ userKey: 'myci_user' }, {}),
given({ passKey: 'myci_pass' }, {}),
]).expect(true)
forCases([
// Partly configured.
given(
{ userKey: 'myci_user', passKey: 'myci_pass', isRequired: true },
{ myci_user: 'admin' }
),
given(
{ userKey: 'myci_user', passKey: 'myci_pass' },
{ myci_user: 'admin' }
),
// Missing required config.
given(
{ userKey: 'myci_user', passKey: 'myci_pass', isRequired: true },
{}
),
given({ userKey: 'myci_user', isRequired: true }, {}),
given({ passKey: 'myci_pass', isRequired: true }, {}),
]).expect(false)
})
})
describe('basicAuth', function() {
function validate(config, privateConfig) {
return new AuthHelper(config, privateConfig).basicAuth
}
test(validate, () => {
forCases([
given(
{ userKey: 'myci_user', passKey: 'myci_pass', isRequired: true },
{ myci_user: 'admin', myci_pass: 'abc123' }
),
given(
{ userKey: 'myci_user', passKey: 'myci_pass' },
{ myci_user: 'admin', myci_pass: 'abc123' }
),
]).expect({ user: 'admin', pass: 'abc123' })
given({ userKey: 'myci_user' }, { myci_user: 'admin' }).expect({
user: 'admin',
pass: undefined,
})
given({ passKey: 'myci_pass' }, { myci_pass: 'abc123' }).expect({
user: undefined,
pass: 'abc123',
})
given({ userKey: 'myci_user', passKey: 'myci_pass' }, {}).expect(
undefined
)
given(
{ passKey: 'myci_pass', defaultToEmptyStringForUser: true },
{ myci_pass: 'abc123' }
).expect({
user: '',
pass: 'abc123',
})
})
})
})

View File

@@ -0,0 +1,92 @@
/**
* @module
*/
'use strict'
const { print } = require('graphql/language/printer')
const BaseService = require('./base')
const { InvalidResponse, ShieldsRuntimeError } = require('./errors')
const { parseJson } = require('./json')
function defaultTransformErrors(errors) {
return new InvalidResponse({ prettyMessage: errors[0].message })
}
/**
* Services which query a GraphQL endpoint should extend BaseGraphqlService
*
* @abstract
*/
class BaseGraphqlService extends BaseService {
/**
* Parse data from JSON endpoint
*
* @param {string} buffer JSON repsonse from upstream API
* @returns {object} Parsed response
*/
_parseJson(buffer) {
return parseJson(buffer)
}
/**
* Request data from an upstream GraphQL API,
* parse it and validate against a schema
*
* @param {object} attrs Refer to individual attrs
* @param {Joi} attrs.schema Joi schema to validate the response against
* @param {string} attrs.url URL to request
* @param {object} attrs.query Parsed GraphQL object
* representing the query clause of GraphQL POST body
* e.g. gql`{ query { ... } }`
* @param {object} attrs.variables Variables clause of GraphQL POST body
* @param {object} [attrs.options={}] Options to pass to request. See
* [documentation](https://github.com/request/request#requestoptions-callback)
* @param {object} [attrs.httpErrorMessages={}] Key-value map of HTTP status codes
* and custom error messages e.g: `{ 404: 'package not found' }`.
* This can be used to extend or override the
* [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5)
* @param {Function} [attrs.transformErrors=defaultTransformErrors]
* Function which takes an errors object from a GraphQL
* response and returns an instance of ShieldsRuntimeError.
* The default is to return the first entry of the `errors` array as
* an InvalidResponse.
* @returns {object} Parsed response
* @see https://github.com/request/request#requestoptions-callback
*/
async _requestGraphql({
schema,
url,
query,
variables = {},
options = {},
httpErrorMessages = {},
transformErrors = defaultTransformErrors,
}) {
const mergedOptions = {
...{ headers: { Accept: 'application/json' } },
...options,
}
mergedOptions.method = 'POST'
mergedOptions.body = JSON.stringify({ query: print(query), variables })
const { buffer } = await this._request({
url,
options: mergedOptions,
errorMessages: httpErrorMessages,
})
const json = this._parseJson(buffer)
if (json.errors) {
const exception = transformErrors(json.errors)
if (exception instanceof ShieldsRuntimeError) {
throw exception
} else {
throw Error(
`transformErrors() must return a ShieldsRuntimeError; got ${exception}`
)
}
}
return this.constructor._validate(json, schema)
}
}
module.exports = BaseGraphqlService

View File

@@ -0,0 +1,209 @@
'use strict'
const Joi = require('@hapi/joi')
const { expect } = require('chai')
const gql = require('graphql-tag')
const sinon = require('sinon')
const BaseGraphqlService = require('./base-graphql')
const { InvalidResponse } = require('./errors')
const dummySchema = Joi.object({
requiredString: Joi.string().required(),
}).required()
class DummyGraphqlService extends BaseGraphqlService {
static get category() {
return 'cat'
}
static get route() {
return {
base: 'foo',
}
}
async handle() {
const { requiredString } = await this._requestGraphql({
schema: dummySchema,
url: 'http://example.com/graphql',
query: gql`
query {
requiredString
}
`,
})
return { message: requiredString }
}
}
describe('BaseGraphqlService', function() {
describe('Making requests', function() {
let sendAndCacheRequest
beforeEach(function() {
sendAndCacheRequest = sinon.stub().returns(
Promise.resolve({
buffer: '{"some": "json"}',
res: { statusCode: 200 },
})
)
})
it('invokes _sendAndCacheRequest', async function() {
await DummyGraphqlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/graphql',
{
body: '{"query":"{\\n requiredString\\n}\\n","variables":{}}',
headers: { Accept: 'application/json' },
method: 'POST',
}
)
})
it('forwards options to _sendAndCacheRequest', async function() {
class WithOptions extends DummyGraphqlService {
async handle() {
const { value } = await this._requestGraphql({
schema: dummySchema,
url: 'http://example.com/graphql',
query: gql`
query {
requiredString
}
`,
options: { qs: { queryParam: 123 } },
})
return { message: value }
}
}
await WithOptions.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
expect(sendAndCacheRequest).to.have.been.calledOnceWith(
'http://example.com/graphql',
{
body: '{"query":"{\\n requiredString\\n}\\n","variables":{}}',
headers: { Accept: 'application/json' },
method: 'POST',
qs: { queryParam: 123 },
}
)
})
})
describe('Making badges', function() {
it('handles valid json responses', async function() {
const sendAndCacheRequest = async () => ({
buffer: '{"requiredString": "some-string"}',
res: { statusCode: 200 },
})
expect(
await DummyGraphqlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
message: 'some-string',
})
})
it('handles json responses which do not match the schema', async function() {
const sendAndCacheRequest = async () => ({
buffer: '{"unexpectedKey": "some-string"}',
res: { statusCode: 200 },
})
expect(
await DummyGraphqlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'invalid response data',
})
})
it('handles unparseable json responses', async function() {
const sendAndCacheRequest = async () => ({
buffer: 'not json',
res: { statusCode: 200 },
})
expect(
await DummyGraphqlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'unparseable json response',
})
})
})
describe('Error handling', function() {
it('handles generic error', async function() {
const sendAndCacheRequest = async () => ({
buffer: '{ "errors": [ { "message": "oh noes!!" } ] }',
res: { statusCode: 200 },
})
expect(
await DummyGraphqlService.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'oh noes!!',
})
})
it('handles custom error', async function() {
class WithErrorHandler extends DummyGraphqlService {
async handle() {
const { requiredString } = await this._requestGraphql({
schema: dummySchema,
url: 'http://example.com/graphql',
query: gql`
query {
requiredString
}
`,
transformErrors: function(errors) {
if (errors[0].message === 'oh noes!!') {
return new InvalidResponse({
prettyMessage: 'a terrible thing has happened',
})
}
},
})
return { message: requiredString }
}
}
const sendAndCacheRequest = async () => ({
buffer: '{ "errors": [ { "message": "oh noes!!" } ] }',
res: { statusCode: 200 },
})
expect(
await WithErrorHandler.invoke(
{ sendAndCacheRequest },
{ handleInternalErrors: false }
)
).to.deep.equal({
isError: true,
color: 'lightgray',
message: 'a terrible thing has happened',
})
})
})
})

View File

@@ -1,30 +1,44 @@
/**
* @module
*/
'use strict'
// See available emoji at http://emoji.muan.co/
const emojic = require('emojic')
const BaseService = require('./base')
const trace = require('./trace')
const { InvalidResponse } = require('./errors')
const { parseJson } = require('./json')
/**
* Services which query a JSON endpoint should extend BaseJsonService
*
* @abstract
*/
class BaseJsonService extends BaseService {
/**
* Parse data from JSON endpoint
*
* @param {string} buffer JSON repsonse from upstream API
* @returns {object} Parsed response
*/
_parseJson(buffer) {
const logTrace = (...args) => trace.logTrace('fetch', ...args)
let json
try {
json = JSON.parse(buffer)
} catch (err) {
logTrace(emojic.dart, 'Response JSON (unparseable)', buffer)
throw new InvalidResponse({
prettyMessage: 'unparseable json response',
underlyingError: err,
})
}
logTrace(emojic.dart, 'Response JSON (before validation)', json, {
deep: true,
})
return json
return parseJson(buffer)
}
/**
* Request data from an upstream API serving JSON,
* parse it and validate against a schema
*
* @param {object} attrs Refer to individual attrs
* @param {Joi} attrs.schema Joi schema to validate the response against
* @param {string} attrs.url URL to request
* @param {object} [attrs.options={}] Options to pass to request. See
* [documentation](https://github.com/request/request#requestoptions-callback)
* @param {object} [attrs.errorMessages={}] Key-value map of status codes
* and custom error messages e.g: `{ 404: 'package not found' }`.
* This can be used to extend or override the
* [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5)
* @returns {object} Parsed response
* @see https://github.com/request/request#requestoptions-callback
*/
async _requestJson({ schema, url, options = {}, errorMessages = {} }) {
const mergedOptions = {
...{ headers: { Accept: 'application/json' } },

View File

@@ -1,6 +1,6 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
const { expect } = require('chai')
const sinon = require('sinon')
const BaseJsonService = require('./base-json')

View File

@@ -2,6 +2,7 @@
const makeBadge = require('../../gh-badges/lib/make-badge')
const BaseService = require('./base')
const { MetricHelper } = require('./metric-helper')
const { setCacheHeaders } = require('./cache-headers')
const { makeSend } = require('./legacy-result-sender')
const coalesceBadge = require('./coalesce-badge')
@@ -24,16 +25,19 @@ const { prepareRoute, namedParamsForMatch } = require('./route')
// configured by the service, the user's request, and the server's default
// cache length.
module.exports = class NonMemoryCachingBaseService extends BaseService {
static register({ camp, requestCounter }, serviceConfig) {
static register({ camp, metricInstance }, serviceConfig) {
const { cacheHeaders: cacheHeaderConfig } = serviceConfig
const { _cacheLength: serviceDefaultCacheLengthSeconds } = this
const { regex, captureNames } = prepareRoute(this.route)
const serviceRequestCounter = this._createServiceRequestCounter({
requestCounter,
const metricHelper = MetricHelper.create({
metricInstance,
ServiceClass: this,
})
camp.route(regex, async (queryParams, match, end, ask) => {
const metricHandle = metricHelper.startRequest()
const namedParams = namedParamsForMatch(captureNames, match, this)
const serviceData = await this.invoke(
{},
@@ -50,7 +54,7 @@ module.exports = class NonMemoryCachingBaseService extends BaseService {
)
// The final capture group is the extension.
const format = match.slice(-1)[0]
const format = (match.slice(-1)[0] || '.svg').replace(/^\./, '')
badgeData.format = format
const svg = makeBadge(badgeData)
@@ -64,7 +68,7 @@ module.exports = class NonMemoryCachingBaseService extends BaseService {
makeSend(format, ask.res, end)(svg)
serviceRequestCounter.inc()
metricHandle.noteResponseSent()
})
}
}

View File

@@ -7,18 +7,20 @@ const {
setCacheHeadersForStaticResource,
} = require('./cache-headers')
const { makeSend } = require('./legacy-result-sender')
const { MetricHelper } = require('./metric-helper')
const coalesceBadge = require('./coalesce-badge')
const { prepareRoute, namedParamsForMatch } = require('./route')
module.exports = class BaseStaticService extends BaseService {
static register({ camp, requestCounter }, serviceConfig) {
static register({ camp, metricInstance }, serviceConfig) {
const {
profiling: { makeBadge: shouldProfileMakeBadge },
} = serviceConfig
const { regex, captureNames } = prepareRoute(this.route)
const serviceRequestCounter = this._createServiceRequestCounter({
requestCounter,
const metricHelper = MetricHelper.create({
metricInstance,
ServiceClass: this,
})
camp.route(regex, async (queryParams, match, end, ask) => {
@@ -29,6 +31,8 @@ module.exports = class BaseStaticService extends BaseService {
return
}
const metricHandle = metricHelper.startRequest()
const namedParams = namedParamsForMatch(captureNames, match, this)
const serviceData = await this.invoke(
{},
@@ -45,7 +49,7 @@ module.exports = class BaseStaticService extends BaseService {
)
// The final capture group is the extension.
const format = match.slice(-1)[0]
const format = (match.slice(-1)[0] || '.svg').replace(/^\./, '')
badgeData.format = format
if (shouldProfileMakeBadge) {
@@ -60,7 +64,7 @@ module.exports = class BaseStaticService extends BaseService {
makeSend(format, ask.res, end)(svg)
serviceRequestCounter.inc()
metricHandle.noteResponseSent()
})
}
}

View File

@@ -1,3 +1,7 @@
/**
* @module
*/
'use strict'
// See available emoji at http://emoji.muan.co/
@@ -9,7 +13,21 @@ const { InvalidResponse } = require('./errors')
const defaultValueMatcher = />([^<>]+)<\/text><\/g>/
const leadingWhitespace = /(?:\r\n\s*|\r\s*|\n\s*)/g
/**
* Services which scrape data from another SVG badge
* should extend BaseSvgScrapingService
*
* @abstract
*/
class BaseSvgScrapingService extends BaseService {
/**
* Extract a value from SVG
*
* @param {string} svg SVG to parse
* @param {RegExp} [valueMatcher=defaultValueMatcher]
* RegExp to match the value we want to parse from the SVG
* @returns {string} Matched value
*/
static valueFromSvgBadge(svg, valueMatcher = defaultValueMatcher) {
if (typeof svg !== 'string') {
throw new TypeError('Parameter should be a string')
@@ -26,6 +44,24 @@ class BaseSvgScrapingService extends BaseService {
}
}
/**
* Request data from an endpoint serving SVG,
* parse a value from it and validate against a schema
*
* @param {object} attrs Refer to individual attrs
* @param {Joi} attrs.schema Joi schema to validate the response against
* @param {RegExp} attrs.valueMatcher
* RegExp to match the value we want to parse from the SVG
* @param {string} attrs.url URL to request
* @param {object} [attrs.options={}] Options to pass to request. See
* [documentation](https://github.com/request/request#requestoptions-callback)
* @param {object} [attrs.errorMessages={}] Key-value map of status codes
* and custom error messages e.g: `{ 404: 'package not found' }`.
* This can be used to extend or override the
* [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5)
* @returns {object} Parsed response
* @see https://github.com/request/request#requestoptions-callback
*/
async _requestSvg({
schema,
valueMatcher,

View File

@@ -2,7 +2,7 @@
const { expect } = require('chai')
const sinon = require('sinon')
const Joi = require('joi')
const Joi = require('@hapi/joi')
const makeBadge = require('../../gh-badges/lib/make-badge')
const BaseSvgScrapingService = require('./base-svg-scraping')

View File

@@ -1,3 +1,7 @@
/**
* @module
*/
'use strict'
// See available emoji at http://emoji.muan.co/
@@ -7,7 +11,31 @@ const BaseService = require('./base')
const trace = require('./trace')
const { InvalidResponse } = require('./errors')
/**
* Services which query a XML endpoint should extend BaseXmlService
*
* @abstract
*/
class BaseXmlService extends BaseService {
/**
* Request data from an upstream API serving XML,
* parse it and validate against a schema
*
* @param {object} attrs Refer to individual attrs
* @param {Joi} attrs.schema Joi schema to validate the response against
* @param {string} attrs.url URL to request
* @param {object} [attrs.options={}] Options to pass to request. See
* [documentation](https://github.com/request/request#requestoptions-callback)
* @param {object} [attrs.errorMessages={}] Key-value map of status codes
* and custom error messages e.g: `{ 404: 'package not found' }`.
* This can be used to extend or override the
* [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5)
* @param {object} [attrs.parserOptions={}] Options to pass to fast-xml-parser. See
* [documentation](https://github.com/NaturalIntelligence/fast-xml-parser#xml-to-json)
* @returns {object} Parsed response
* @see https://github.com/request/request#requestoptions-callback
* @see https://github.com/NaturalIntelligence/fast-xml-parser#xml-to-json
*/
async _requestXml({
schema,
url,

View File

@@ -1,6 +1,6 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
const { expect } = require('chai')
const sinon = require('sinon')
const BaseXmlService = require('./base-xml')

View File

@@ -1,3 +1,7 @@
/**
* @module
*/
'use strict'
const emojic = require('emojic')
@@ -6,7 +10,29 @@ const BaseService = require('./base')
const { InvalidResponse } = require('./errors')
const trace = require('./trace')
/**
* Services which query a YAML endpoint should extend BaseYamlService
*
* @abstract
*/
class BaseYamlService extends BaseService {
/**
* Request data from an upstream API serving YAML,
* parse it and validate against a schema
*
* @param {object} attrs Refer to individual attrs
* @param {Joi} attrs.schema Joi schema to validate the response against
* @param {string} attrs.url URL to request
* @param {object} [attrs.options={}] Options to pass to request. See
* [documentation](https://github.com/request/request#requestoptions-callback)
* @param {object} [attrs.errorMessages={}] Key-value map of status codes
* and custom error messages e.g: `{ 404: 'package not found' }`.
* This can be used to extend or override the
* [default](https://github.com/badges/shields/blob/master/core/base-service/check-error-response.js#L5)
* @param {object} [attrs.encoding='utf8'] Character encoding
* @returns {object} Parsed response
* @see https://github.com/request/request#requestoptions-callback
*/
async _requestYaml({
schema,
url,

View File

@@ -1,6 +1,6 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
const { expect } = require('chai')
const sinon = require('sinon')
const BaseYamlService = require('./base-yaml')

View File

@@ -1,9 +1,14 @@
'use strict'
/**
* @module
*/
const decamelize = require('decamelize')
// See available emoji at http://emoji.muan.co/
const emojic = require('emojic')
const Joi = require('joi')
const Joi = require('@hapi/joi')
const log = require('../server/log')
const { AuthHelper } = require('./auth-helper')
const { MetricHelper } = require('./metric-helper')
const { assertValidCategory } = require('./categories')
const checkErrorResponse = require('./check-error-response')
const coalesceBadge = require('./coalesce-badge')
@@ -11,6 +16,7 @@ const {
NotFound,
InvalidResponse,
Inaccessible,
ImproperlyConfigured,
InvalidParameter,
Deprecated,
} = require('./errors')
@@ -33,14 +39,17 @@ const defaultBadgeDataSchema = Joi.object({
namedLogo: Joi.string(),
}).required()
const optionalStringWhenNamedLogoPrsent = Joi.alternatives().when('namedLogo', {
is: Joi.string().required(),
then: Joi.string(),
})
const optionalStringWhenNamedLogoPresent = Joi.alternatives().conditional(
'namedLogo',
{
is: Joi.string().required(),
then: Joi.string(),
}
)
const optionalNumberWhenAnyLogoPresent = Joi.alternatives()
.when('namedLogo', { is: Joi.string().required(), then: Joi.number() })
.when('logoSvg', { is: Joi.string().required(), then: Joi.number() })
.conditional('namedLogo', { is: Joi.string().required(), then: Joi.number() })
.conditional('logoSvg', { is: Joi.string().required(), then: Joi.number() })
const serviceDataSchema = Joi.object({
isError: Joi.boolean(),
@@ -58,7 +67,7 @@ const serviceDataSchema = Joi.object({
labelColor: Joi.string(),
namedLogo: Joi.string(),
logoSvg: Joi.string(),
logoColor: optionalStringWhenNamedLogoPrsent,
logoColor: optionalStringWhenNamedLogoPresent,
logoWidth: optionalNumberWhenAnyLogoPresent,
logoPosition: optionalNumberWhenAnyLogoPresent,
cacheSeconds: Joi.number()
@@ -69,10 +78,18 @@ const serviceDataSchema = Joi.object({
.oxor('namedLogo', 'logoSvg')
.required()
module.exports = class BaseService {
/**
* Abstract base class which all service classes inherit from.
* Concrete implementations of BaseService must implement the methods
* category(), route() and handle(namedParams, queryParams)
*/
class BaseService {
/**
* Name of the category to sort this badge into (eg. "build"). Used to sort
* the badges on the main shields.io website.
*
* @abstract
* @type {string}
*/
static get category() {
throw new Error(`Category not set for ${this.name}`)
@@ -83,38 +100,38 @@ module.exports = class BaseService {
}
/**
* Returns an object:
* - base: (Optional) The base path of the routes for this service. This is
* used as a prefix.
* - format: Regular expression to use for routes for this service's badges
* - capture: Array of names for the capture groups in the regular
* expression. The handler will be passed an object containing
* the matches.
* - queryParamSchema: (Optional) A Joi schema (`Joi.object({ ... }).required()`)
* for the query param object. If you know a parameter
* will never receive a numeric string, you can use
* `Joi.string()`. Because of quirks in Scoutcamp and Joi,
* alphanumeric strings should be declared using
* `Joi.alternatives().try(Joi.string(), Joi.number())`,
* otherwise a value like `?success_color=999` will fail.
* A parameter requiring a numeric string can use
* `Joi.number()`. A parameter that receives only non-numeric
* strings can use `Joi.string()`. A parameter that never
* receives numeric can use `Joi.string()`. A boolean
* parameter should use `Joi.equal('')` and will receive an
* empty string on e.g. `?compact_message` and undefined
* when the parameter is absent. (Note that in,
* `examples.queryParams` boolean query params should be given
* `null` values.)
* Route to mount this service on
*
* @abstract
* @type {module:core/base-service/base~Route}
*/
static get route() {
throw new Error(`Route not defined for ${this.name}`)
}
/**
* Example URLs for this service. These should use the format
* specified in `route`, and can be used to demonstrate how to use badges for
* this service.
* Configuration for the authentication helper that prepares credentials
* for upstream requests.
*
* See also the config schema in `./server.js` and `doc/server-secrets.md`.
*
* To use the configured auth in the handler or fetch method, pass the
* credentials to the request. For example:
* - `{ options: { auth: this.authHelper.basicAuth } }`
* - `{ options: { headers: this.authHelper.bearerAuthHeader } }`
* - `{ options: { qs: { token: this.authHelper.pass } } }`
*
* @abstract
* @type {module:core/base-service/base~Auth}
*/
static get auth() {
return undefined
}
/**
* Array of Example objects describing example URLs for this service.
* These should use the format specified in `route`,
* and can be used to demonstrate how to use badges for this service.
*
* The preferred way to specify an example is with `namedParams` which are
* substituted into the service's compiled route pattern. The rendered badge
@@ -123,21 +140,9 @@ module.exports = class BaseService {
* For services which use a route `format`, the `pattern` can be specified as
* part of the example.
*
* title: Descriptive text that will be shown next to the badge. The default
* is to use the service class name, which probably is not what you want.
* namedParams: An object containing the values of named parameters to
* substitute into the compiled route pattern.
* queryParams: An object containing query parameters to include in the
* example URLs. For alphanumeric query parameters, specify a string value.
* For boolean query parameters, specify `null`.
* pattern: The route pattern to compile. Defaults to `this.route.pattern`.
* staticPreview: A rendered badge of the sort returned by `handle()` or
* `render()`: an object containing `message` and optional `label` and
* `color`. This is usually generated by invoking `this.render()` with some
* explicit props.
* keywords: Additional keywords, other than words in the title. This helps
* users locate relevant badges.
* documentation: An HTML string that is included in the badge popup.
* @see {@link module:core/base-service/base~Example}
* @abstract
* @type {module:core/base-service/base~Example[]}
*/
static get examples() {
return []
@@ -154,9 +159,11 @@ module.exports = class BaseService {
}
/**
* Default data for the badge. Can include label, logo, and color. These
* defaults are used if the value is neither included in the service data
* Default data for the badge.
* These defaults are used if the value is neither included in the service data
* from the handler nor overridden by the user via query parameters.
*
* @type {module:core/base-service/base~DefaultBadgeData}
*/
static get defaultBadgeData() {
return {}
@@ -207,8 +214,9 @@ module.exports = class BaseService {
return result
}
constructor({ sendAndCacheRequest }, { handleInternalErrors }) {
constructor({ sendAndCacheRequest, authHelper }, { handleInternalErrors }) {
this._requestFetcher = sendAndCacheRequest
this.authHelper = authHelper
this._handleInternalErrors = handleInternalErrors
}
@@ -247,6 +255,13 @@ module.exports = class BaseService {
* Asynchronous function to handle requests for this service. Take the route
* parameters (as defined in the `route` property), perform a request using
* `this._sendAndCacheRequest`, and return the badge data.
*
* @abstract
* @param {object} namedParams Params parsed from route pattern
* defined in this.route.pattern or this.route.capture
* @param {object} queryParams Params parsed from the query string
* @returns {module:core/base-service/base~Badge}
* badge Object validated against serviceDataSchema
*/
async handle(namedParams, queryParams) {
throw new Error(`Handler not implemented for ${this.constructor.name}`)
@@ -261,6 +276,7 @@ module.exports = class BaseService {
color: 'red',
}
} else if (
error instanceof ImproperlyConfigured ||
error instanceof InvalidResponse ||
error instanceof Inaccessible ||
error instanceof Deprecated
@@ -281,8 +297,8 @@ module.exports = class BaseService {
)
) {
// This is where we end up if an unhandled exception is thrown in
// production. Send the error to the logs.
console.log(error)
// production. Send the error to Sentry and the logs.
log.error(error)
}
return {
isError: true,
@@ -311,12 +327,26 @@ module.exports = class BaseService {
trace.logTrace('inbound', emojic.ticket, 'Named params', namedParams)
trace.logTrace('inbound', emojic.crayon, 'Query params', queryParams)
const serviceInstance = new this(context, config)
// Like the service instance, the auth helper could be reused for each request.
// However, moving its instantiation to `register()` makes `invoke()` harder
// to test.
const authHelper = this.auth
? new AuthHelper(this.auth, config.private)
: undefined
const serviceInstance = new this({ ...context, authHelper }, config)
let serviceError
if (authHelper && !authHelper.isValid) {
const prettyMessage = authHelper.isRequired
? 'credentials have not been configured'
: 'credentials are misconfigured'
serviceError = new ImproperlyConfigured({ prettyMessage })
}
const { queryParamSchema } = this.route
let transformedQueryParams
if (queryParamSchema) {
if (!serviceError && queryParamSchema) {
try {
transformedQueryParams = validate(
{
@@ -364,27 +394,17 @@ module.exports = class BaseService {
return serviceData
}
static _createServiceRequestCounter({ requestCounter }) {
if (requestCounter) {
const { category, serviceFamily, name } = this
const service = decamelize(name)
return requestCounter.labels(category, serviceFamily, service)
} else {
// When metrics are disabled, return a mock counter.
return { inc: () => {} }
}
}
static register(
{ camp, handleRequest, githubApiProvider, requestCounter },
{ camp, handleRequest, githubApiProvider, metricInstance },
serviceConfig
) {
const { cacheHeaders: cacheHeaderConfig, fetchLimitBytes } = serviceConfig
const { regex, captureNames } = prepareRoute(this.route)
const queryParams = getQueryParamNames(this.route)
const serviceRequestCounter = this._createServiceRequestCounter({
requestCounter,
const metricHelper = MetricHelper.create({
metricInstance,
ServiceClass: this,
})
camp.route(
@@ -392,6 +412,8 @@ module.exports = class BaseService {
handleRequest(cacheHeaderConfig, {
queryParams,
handler: async (queryParams, match, sendBadge, request) => {
const metricHandle = metricHelper.startRequest()
const namedParams = namedParamsForMatch(captureNames, match, this)
const serviceData = await this.invoke(
{
@@ -411,10 +433,10 @@ module.exports = class BaseService {
this
)
// The final capture group is the extension.
const format = match.slice(-1)[0]
const format = (match.slice(-1)[0] || '.svg').replace(/^\./, '')
sendBadge(format, badgeData)
serviceRequestCounter.inc()
metricHandle.noteResponseSent()
},
cacheLength: this._cacheLength,
fetchLimitBytes,
@@ -422,3 +444,99 @@ module.exports = class BaseService {
)
}
}
/**
* Default badge properties, validated against defaultBadgeDataSchema
*
* @typedef {object} DefaultBadgeData
* @property {string} label (Optional)
* @property {string} color (Optional)
* @property {string} labelColor (Optional)
* @property {string} namedLogo (Optional)
*/
/**
* Badge Object, validated against serviceDataSchema
*
* @typedef {object} Badge
* @property {boolean} isError (Optional)
* @property {string} label (Optional)
* @property {(string|number)} message
* @property {string} color (Optional)
* @property {string[]} link (Optional)
*/
/**
* @typedef {object} Route
* @property {string} base
* (Optional) The base path of the routes for this service.
* This is used as a prefix.
* @property {string} pattern
* A path-to-regexp pattern defining the route pattern and param names
* See {@link https://www.npmjs.com/package/path-to-regexp}
* @property {RegExp} format
* Deprecated: Regular expression to use for routes for this service's badges
* Use `pattern` instead
* @property {string[]} capture
* Deprecated: Array of names for the capture groups in the regular
* expression. The handler will be passed an object containing
* the matches.
* Use `pattern` instead
* @property {Joi.object} queryParamSchema
* (Optional) A Joi schema (`Joi.object({ ... }).required()`)
* for the query param object. If you know a parameter
* will never receive a numeric string, you can use
* `Joi.string()`. Because of quirks in Scoutcamp and Joi,
* alphanumeric strings should be declared using
* `Joi.alternatives().try(Joi.string(), Joi.number())`,
* otherwise a value like `?success_color=999` will fail.
* A parameter requiring a numeric string can use
* `Joi.number()`. A parameter that receives only non-numeric
* strings can use `Joi.string()`. A parameter that never
* receives numeric can use `Joi.string()`. A boolean
* parameter should use `Joi.equal('')` and will receive an
* empty string on e.g. `?compact_message` and undefined
* when the parameter is absent. (Note that in,
* `examples.queryParams` boolean query params should be given
* `null` values.)
*/
/**
* @typedef {object} Auth
* @property {string} userKey
* (Optional) The key from `privateConfig` to use as the username.
* @property {string} passKey
* (Optional) The key from `privateConfig` to use as the password.
* If auth is configured, either `userKey` or `passKey` is required.
* @property {string} isRequired
* (Optional) If `true`, the service will return `NotFound` unless the
* configured credentials are present.
*/
/**
* @typedef {object} Example
* @property {string} title
* Descriptive text that will be shown next to the badge. The default
* is to use the service class name, which probably is not what you want.
* @property {object} namedParams
* An object containing the values of named parameters to
* substitute into the compiled route pattern.
* @property {object} queryParams
* An object containing query parameters to include in the
* example URLs. For alphanumeric query parameters, specify a string value.
* For boolean query parameters, specify `null`.
* @property {string} pattern
* The route pattern to compile. Defaults to `this.route.pattern`.
* @property {object} staticPreview
* A rendered badge of the sort returned by `handle()` or
* `render()`: an object containing `message` and optional `label` and
* `color`. This is usually generated by invoking `this.render()` with some
* explicit props.
* @property {string[]} keywords
* Additional keywords, other than words in the title. This helps
* users locate relevant badges.
* @property {string} documentation
* An HTML string that is included in the badge popup.
*/
module.exports = BaseService

View File

@@ -1,6 +1,6 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
const { expect } = require('chai')
const sinon = require('sinon')
const trace = require('./trace')
@@ -64,7 +64,7 @@ class DummyService extends BaseService {
}
describe('BaseService', function() {
const defaultConfig = { handleInternalErrors: false }
const defaultConfig = { handleInternalErrors: false, private: {} }
it('Invokes the handler as expected', async function() {
expect(
@@ -316,7 +316,9 @@ describe('BaseService', function() {
})
describe('ScoutCamp integration', function() {
const expectedRouteRegex = /^\/foo\/([^/]+?)\.(svg|png|gif|jpg|json)$/
// TODO Strangly, without the useless escape the regexes do not match in Node 12.
// eslint-disable-next-line no-useless-escape
const expectedRouteRegex = /^\/foo\/([^\/]+?)(|\.svg|\.json)$/
let mockCamp
let mockHandleRequest
@@ -482,4 +484,43 @@ describe('BaseService', function() {
}
})
})
describe('auth', function() {
class AuthService extends DummyService {
static get auth() {
return {
passKey: 'myci_pass',
isRequired: true,
}
}
async handle() {
return {
message: `The CI password is ${this.authHelper.pass}`,
}
}
}
it('when auth is configured properly, invoke() sets authHelper', async function() {
expect(
await AuthService.invoke(
{},
{ defaultConfig, private: { myci_pass: 'abc123' } },
{ namedParamA: 'bar.bar.bar' }
)
).to.deep.equal({ message: 'The CI password is abc123' })
})
it('when auth is not configured properly, invoke() returns inacessible', async function() {
expect(
await AuthService.invoke({}, defaultConfig, {
namedParamA: 'bar.bar.bar',
})
).to.deep.equal({
color: 'lightgray',
isError: true,
message: 'credentials have not been configured',
})
})
})
})

View File

@@ -1,7 +1,7 @@
'use strict'
const assert = require('assert')
const Joi = require('joi')
const Joi = require('@hapi/joi')
const coalesce = require('./coalesce')
const serverStartTimeGMTString = new Date().toGMTString()

View File

@@ -1,9 +1,9 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
const categories = require('../../services/categories')
const isRealCategory = Joi.equal(categories.map(({ id }) => id)).required()
const isRealCategory = Joi.equal(...categories.map(({ id }) => id)).required()
const isValidCategory = Joi.alternatives()
.try(isRealCategory, Joi.equal('debug', 'dynamic', 'static').required())

View File

@@ -1,6 +1,6 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
const camelcase = require('camelcase')
const BaseService = require('./base')
const { isValidCategory } = require('./categories')

View File

@@ -1,13 +1,43 @@
/**
* Standard exceptions for handling error cases
*
* @module
*/
'use strict'
/**
* Base error class
*
* @abstract
*/
class ShieldsRuntimeError extends Error {
/**
* Name of the class. Implementations of ShieldsRuntimeError
* should override this method.
*
* @type {string}
*/
get name() {
return 'ShieldsRuntimeError'
}
/**
* Default message for this exception if none is specified.
* Implementations of ShieldsRuntimeError should implement this method.
*
* @abstract
* @type {string}
*/
get defaultPrettyMessage() {
throw new Error('Must implement abstract method')
}
/**
* @param {module:core/base-service/errors~RuntimeErrorProps} props
* Refer to individual attrs
* @param {string} message Exception message for debug purposes
*/
constructor(props = {}, message) {
super(message)
this.prettyMessage = props.prettyMessage || this.defaultPrettyMessage
@@ -19,6 +49,9 @@ class ShieldsRuntimeError extends Error {
const defaultNotFoundError = 'not found'
/**
* Throw this to wrap a 404 or other 'not found' response from an upstream API
*/
class NotFound extends ShieldsRuntimeError {
get name() {
return 'NotFound'
@@ -27,6 +60,10 @@ class NotFound extends ShieldsRuntimeError {
return defaultNotFoundError
}
/**
* @param {module:core/base-service/errors~RuntimeErrorProps} props
* Refer to individual attrs
*/
constructor(props = {}) {
const prettyMessage = props.prettyMessage || defaultNotFoundError
const message =
@@ -38,6 +75,9 @@ class NotFound extends ShieldsRuntimeError {
}
}
/**
* Throw this to wrap an invalid or unexpected response from an upstream API
*/
class InvalidResponse extends ShieldsRuntimeError {
get name() {
return 'InvalidResponse'
@@ -46,6 +86,10 @@ class InvalidResponse extends ShieldsRuntimeError {
return 'invalid'
}
/**
* @param {module:core/base-service/errors~RuntimeErrorProps} props
* Refer to individual attrs
*/
constructor(props = {}) {
const message = props.underlyingError
? `Invalid Response: ${props.underlyingError.message}`
@@ -55,6 +99,10 @@ class InvalidResponse extends ShieldsRuntimeError {
}
}
/**
* Throw this if we can't contact an upstream API
* or to wrap a 5XX response
*/
class Inaccessible extends ShieldsRuntimeError {
get name() {
return 'Inaccessible'
@@ -63,6 +111,10 @@ class Inaccessible extends ShieldsRuntimeError {
return 'inaccessible'
}
/**
* @param {module:core/base-service/errors~RuntimeErrorProps} props
* Refer to individual attrs
*/
constructor(props = {}) {
const message = props.underlyingError
? `Inaccessible: ${props.underlyingError.message}`
@@ -72,6 +124,34 @@ class Inaccessible extends ShieldsRuntimeError {
}
}
/**
* Throw this error when required credentials are missing
*/
class ImproperlyConfigured extends ShieldsRuntimeError {
get name() {
return 'ImproperlyConfigured'
}
get defaultPrettyMessage() {
return 'improperly configured'
}
/**
* @param {module:core/base-service/errors~RuntimeErrorProps} props
* Refer to individual attrs
*/
constructor(props = {}) {
const message = props.underlyingError
? `ImproperlyConfigured: ${props.underlyingError.message}`
: 'ImproperlyConfigured'
super(props, message)
this.response = props.response
}
}
/**
* Throw this error when a user supplied input or parameter
* is invalid or unexpected
*/
class InvalidParameter extends ShieldsRuntimeError {
get name() {
return 'InvalidParameter'
@@ -80,6 +160,10 @@ class InvalidParameter extends ShieldsRuntimeError {
return 'invalid parameter'
}
/**
* @param {module:core/base-service/errors~RuntimeErrorProps} props
* Refer to individual attrs
*/
constructor(props = {}) {
const message = props.underlyingError
? `Invalid Parameter: ${props.underlyingError.message}`
@@ -89,6 +173,9 @@ class InvalidParameter extends ShieldsRuntimeError {
}
}
/**
* Throw this error to indicate that a service is deprecated or removed
*/
class Deprecated extends ShieldsRuntimeError {
get name() {
return 'Deprecated'
@@ -97,15 +184,30 @@ class Deprecated extends ShieldsRuntimeError {
return 'no longer available'
}
/**
* @param {module:core/base-service/errors~RuntimeErrorProps} props
* Refer to individual attrs
*/
constructor(props) {
const message = 'Deprecated'
super(props, message)
}
}
/**
* @typedef {object} RuntimeErrorProps
* @property {Error} underlyingError Exception we are wrapping (Optional)
* @property {object} response Response from an upstream API to provide
* context for the error (Optional)
* @property {string} prettyMessage User-facing error message to override the
* value of `defaultPrettyMessage()`. This is the text that will appear on the
* badge when we catch and render the exception (Optional)
*/
module.exports = {
ShieldsRuntimeError,
NotFound,
ImproperlyConfigured,
InvalidResponse,
Inaccessible,
InvalidParameter,

View File

@@ -1,7 +1,8 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
const pathToRegexp = require('path-to-regexp')
const categories = require('../../services/categories')
const coalesceBadge = require('./coalesce-badge')
const { makeFullUrl } = require('./route')
@@ -47,16 +48,12 @@ function validateExample(example, index, ServiceClass) {
if (!pattern && !ServiceClass.route.pattern) {
throw new Error(
`Example for ${
ServiceClass.name
} at index ${index} does not declare a pattern`
`Example for ${ServiceClass.name} at index ${index} does not declare a pattern`
)
}
if (pattern === ServiceClass.route.pattern) {
throw new Error(
`Example for ${
ServiceClass.name
} at index ${index} declares a redundant pattern which should be removed`
`Example for ${ServiceClass.name} at index ${index} declares a redundant pattern which should be removed`
)
}
@@ -158,7 +155,9 @@ function transformExample(inExample, index, ServiceClass) {
style: style === 'flat' ? undefined : style,
namedLogo,
},
keywords,
keywords: keywords.concat(
categories.find(c => c.id === ServiceClass.category).keywords
),
documentation: documentation ? { __html: documentation } : undefined,
}
}

View File

@@ -84,6 +84,7 @@ test(transformExample, function() {
defaultBadgeData: {
label: 'downloads',
},
category: 'platform-support',
}
given(
@@ -109,7 +110,7 @@ test(transformExample, function() {
namedLogo: undefined,
style: undefined,
},
keywords: ['hello'],
keywords: ['hello', 'platform'],
documentation: undefined,
})
@@ -135,7 +136,7 @@ test(transformExample, function() {
namedLogo: undefined,
style: undefined,
},
keywords: ['hello'],
keywords: ['hello', 'platform'],
documentation: undefined,
})
@@ -162,7 +163,7 @@ test(transformExample, function() {
namedLogo: undefined,
style: undefined,
},
keywords: ['hello'],
keywords: ['hello', 'platform'],
documentation: undefined,
})
})

View File

@@ -0,0 +1,52 @@
'use strict'
/**
* @module
*/
/**
* Utility function to merge two graphql queries together
* This is basically copied from
* [graphql-query-merge](https://www.npmjs.com/package/graphql-query-merge)
* but can't use that due to incorrect packaging.
*
* @param {...object} queries queries to merge
* @returns {object} merged query
*/
function mergeQueries(...queries) {
const merged = {
kind: 'Document',
definitions: [
{
directives: [],
operation: 'query',
variableDefinitions: [],
kind: 'OperationDefinition',
selectionSet: { kind: 'SelectionSet', selections: [] },
},
],
}
queries.forEach(query => {
const parsedQuery = query
parsedQuery.definitions.forEach(definition => {
merged.definitions[0].directives = [
...merged.definitions[0].directives,
...definition.directives,
]
merged.definitions[0].variableDefinitions = [
...merged.definitions[0].variableDefinitions,
...definition.variableDefinitions,
]
merged.definitions[0].selectionSet.selections = [
...merged.definitions[0].selectionSet.selections,
...definition.selectionSet.selections,
]
})
})
return merged
}
module.exports = { mergeQueries }

View File

@@ -0,0 +1,94 @@
'use strict'
const { expect } = require('chai')
const gql = require('graphql-tag')
const { print } = require('graphql/language/printer')
const { mergeQueries } = require('./graphql')
require('../register-chai-plugins.spec')
describe('mergeQueries function', function() {
it('merges valid gql queries', function() {
expect(
print(
mergeQueries(
gql`
query($param: String!) {
foo(param: $param) {
bar
}
}
`
)
)
).to.equalIgnoreSpaces(
'query ($param: String!) { foo(param: $param) { bar } }'
)
expect(
print(
mergeQueries(
gql`
query($param: String!) {
foo(param: $param) {
bar
}
}
`,
gql`
query {
baz
}
`
)
)
).to.equalIgnoreSpaces(
'query ($param: String!) { foo(param: $param) { bar } baz }'
)
expect(
print(
mergeQueries(
gql`
query {
foo
}
`,
gql`
query {
bar
}
`,
gql`
query {
baz
}
`
)
)
).to.equalIgnoreSpaces('{ foo bar baz }')
expect(
print(
mergeQueries(
gql`
{
foo
}
`,
gql`
{
bar
}
`
)
)
).to.equalIgnoreSpaces('{ foo bar }')
})
it('throws an error when passed invalid params', function() {
expect(() => mergeQueries('', '')).to.throw(Error)
expect(() => mergeQueries(undefined, 17, true)).to.throw(Error)
expect(() => mergeQueries(gql``, gql`foo`)).to.throw(Error)
})
})

View File

@@ -2,6 +2,7 @@
const BaseService = require('./base')
const BaseJsonService = require('./base-json')
const BaseGraphqlService = require('./base-graphql')
const NonMemoryCachingBaseService = require('./base-non-memory-caching')
const BaseStaticService = require('./base-static')
const BaseSvgScrapingService = require('./base-svg-scraping')
@@ -20,6 +21,7 @@ const {
module.exports = {
BaseService,
BaseJsonService,
BaseGraphqlService,
NonMemoryCachingBaseService,
BaseStaticService,
BaseSvgScrapingService,

28
core/base-service/json.js Normal file
View File

@@ -0,0 +1,28 @@
'use strict'
// See available emoji at http://emoji.muan.co/
const emojic = require('emojic')
const { InvalidResponse } = require('./errors')
const trace = require('./trace')
function parseJson(buffer) {
const logTrace = (...args) => trace.logTrace('fetch', ...args)
let json
try {
json = JSON.parse(buffer)
} catch (err) {
logTrace(emojic.dart, 'Response JSON (unparseable)', buffer)
throw new InvalidResponse({
prettyMessage: 'unparseable json response',
underlyingError: err,
})
}
logTrace(emojic.dart, 'Response JSON (before validation)', json, {
deep: true,
})
return json
}
module.exports = {
parseJson,
}

View File

@@ -1,12 +1,8 @@
'use strict'
// eslint-disable-next-line node/no-deprecated-api
const domain = require('domain')
const request = require('request')
const queryString = require('query-string')
const LruCache = require('../../gh-badges/lib/lru-cache')
const makeBadge = require('../../gh-badges/lib/make-badge')
const log = require('../server/log')
const { setCacheHeaders } = require('./cache-headers')
const {
Inaccessible,
@@ -14,6 +10,7 @@ const {
ShieldsRuntimeError,
} = require('./errors')
const { makeSend } = require('./legacy-result-sender')
const LruCache = require('./lru-cache')
const coalesceBadge = require('./coalesce-badge')
// We avoid calling the vendor's server for computation of the information in a
@@ -32,12 +29,6 @@ const freqRatioMax = 1 - minAccuracy
// Request cache size of 5MB (~5000 bytes/image).
const requestCache = new LruCache(1000)
// Deep error handling for vendor hooks.
const vendorDomain = domain.create()
vendorDomain.on('error', err => {
log.error('Vendor hook error:', err.stack)
})
// These query parameters are available to any badge. They are handled by
// `coalesceBadge`.
const globalQueryParams = new Set([
@@ -63,6 +54,25 @@ function flattenQueryParams(queryParams) {
return Array.from(union).sort()
}
function promisify(cachingRequest) {
return (uri, options) =>
new Promise((resolve, reject) => {
cachingRequest(uri, options, (err, res, buffer) => {
if (err) {
if (err instanceof ShieldsRuntimeError) {
reject(err)
} else {
// Wrap the error in an Inaccessible so it can be identified
// by the BaseService handler.
reject(new Inaccessible({ underlyingError: err }))
}
} else {
resolve({ res, buffer })
}
})
})
}
// handlerOptions can contain:
// - handler: The service's request handler function
// - queryParams: An array of the field names of any custom query parameters
@@ -175,12 +185,7 @@ function handleRequest(cacheHeaderConfig, handlerOptions) {
{}
)
const svg = makeBadge(badgeData)
let extension
try {
extension = match[0].split('.').pop()
} catch (e) {
extension = 'svg'
}
const extension = (match.slice(-1)[0] || '.svg').replace(/^\./, '')
setCacheHeadersOnResponse(ask.res)
makeSend(extension, ask.res, end)(svg)
}, 25000)
@@ -231,70 +236,51 @@ function handleRequest(cacheHeaderConfig, handlerOptions) {
})
}
// Wrapper around `cachingRequest` that returns a promise rather than
// needing to pass a callback.
cachingRequest.asPromise = (uri, options) =>
new Promise((resolve, reject) => {
cachingRequest(uri, options, (err, res, buffer) => {
if (err) {
if (err instanceof ShieldsRuntimeError) {
reject(err)
} else {
// Wrap the error in an Inaccessible so it can be identified
// by the BaseService handler.
reject(new Inaccessible({ underlyingError: err }))
}
} else {
resolve({ res, buffer })
}
})
})
// Wrapper around `cachingRequest` that returns a promise rather than needing
// to pass a callback.
cachingRequest.asPromise = promisify(cachingRequest)
vendorDomain.run(() => {
const result = handlerOptions.handler(
filteredQueryParams,
match,
// eslint-disable-next-line mocha/prefer-arrow-callback
function sendBadge(format, badgeData) {
if (serverUnresponsive) {
return
}
clearTimeout(serverResponsive)
// Check for a change in the data.
let dataHasChanged = false
if (
cached !== undefined &&
cached.data.badgeData.text[1] !== badgeData.text[1]
) {
dataHasChanged = true
}
// Add format to badge data.
badgeData.format = format
// Update information in the cache.
const updatedCache = {
reqs: cached ? cached.reqs + 1 : 1,
dataChange: cached
? cached.dataChange + (dataHasChanged ? 1 : 0)
: 1,
time: +reqTime,
interval: cacheInterval,
data: { format, badgeData },
}
requestCache.set(cacheIndex, updatedCache)
if (!cachedVersionSent) {
const svg = makeBadge(badgeData)
setCacheHeadersOnResponse(ask.res, badgeData.cacheLengthSeconds)
makeSend(format, ask.res, end)(svg)
}
},
cachingRequest
)
if (result && result.catch) {
result.catch(err => {
throw err
})
}
})
const result = handlerOptions.handler(
filteredQueryParams,
match,
// eslint-disable-next-line mocha/prefer-arrow-callback
function sendBadge(format, badgeData) {
if (serverUnresponsive) {
return
}
clearTimeout(serverResponsive)
// Check for a change in the data.
let dataHasChanged = false
if (
cached !== undefined &&
cached.data.badgeData.text[1] !== badgeData.text[1]
) {
dataHasChanged = true
}
// Add format to badge data.
badgeData.format = format
// Update information in the cache.
const updatedCache = {
reqs: cached ? cached.reqs + 1 : 1,
dataChange: cached ? cached.dataChange + (dataHasChanged ? 1 : 0) : 1,
time: +reqTime,
interval: cacheInterval,
data: { format, badgeData },
}
requestCache.set(cacheIndex, updatedCache)
if (!cachedVersionSent) {
const svg = makeBadge(badgeData)
setCacheHeadersOnResponse(ask.res, badgeData.cacheLengthSeconds)
makeSend(format, ask.res, end)(svg)
}
},
cachingRequest
)
if (result && result.catch) {
result.catch(err => {
throw err
})
}
}
}
@@ -304,6 +290,7 @@ function clearRequestCache() {
module.exports = {
handleRequest,
promisify,
clearRequestCache,
// Expose for testing.
_requestCache: requestCache,

View File

@@ -1,11 +1,10 @@
'use strict'
const { expect } = require('chai')
// https://github.com/nock/nock/issues/1523
const got = require('got').extend({ retry: 0 })
const nock = require('nock')
const portfinder = require('portfinder')
const Camp = require('camp')
const got = require('../got-test-client')
const coalesceBadge = require('./coalesce-badge')
const {
handleRequest,

View File

@@ -1,15 +1,6 @@
'use strict'
const fs = require('fs')
const path = require('path')
const stream = require('stream')
const svg2img = require('../../gh-badges/lib/svg-to-img')
const log = require('../server/log')
const internalError = fs.readFileSync(
path.resolve(__dirname, '..', 'server', 'error-pages', '500.html'),
'utf-8'
)
function streamFromString(str) {
const newStream = new stream.Readable()
@@ -25,21 +16,6 @@ function sendSVG(res, askres, end) {
end(null, { template: streamFromString(res) })
}
function sendOther(format, res, askres, end) {
askres.setHeader('Content-Type', `image/${format}`)
svg2img(res, format)
// This interacts with callback code and can't use async/await.
// eslint-disable-next-line promise/prefer-await-to-then
.then(data => {
end(null, { template: streamFromString(data) })
})
.catch(err => {
// This emits status code 200, though 500 would be preferable.
log.error('svg2img error', err)
end(internalError)
})
}
function sendJSON(res, askres, end) {
askres.setHeader('Content-Type', 'application/json')
askres.setHeader('Access-Control-Allow-Origin', '*')
@@ -52,7 +28,7 @@ function makeSend(format, askres, end) {
} else if (format === 'json') {
return res => sendJSON(res, askres, end)
} else {
return res => sendOther(format, res, askres, end)
throw Error(`Unrecognized format: ${format}`)
}
}

View File

@@ -7,6 +7,23 @@ const typeEnum = {
heap: 1,
}
// In bytes.
let heapSize
function computeHeapSize() {
return (heapSize = process.memoryUsage().heapTotal)
}
let heapSizeTimeout
function getHeapSize() {
if (heapSizeTimeout == null) {
// Compute the heap size every 60 seconds.
heapSizeTimeout = setInterval(computeHeapSize, 60 * 1000)
return computeHeapSize()
} else {
return heapSize
}
}
function CacheSlot(key, value) {
this.key = key
this.value = value
@@ -116,20 +133,4 @@ Cache.prototype = {
},
}
// In bytes.
let heapSize
let heapSizeTimeout
function getHeapSize() {
if (heapSizeTimeout == null) {
// Compute the heap size every 60 seconds.
heapSizeTimeout = setInterval(computeHeapSize, 60 * 1000)
return computeHeapSize()
} else {
return heapSize
}
}
function computeHeapSize() {
return (heapSize = process.memoryUsage().heapTotal)
}
module.exports = Cache

View File

@@ -0,0 +1,45 @@
'use strict'
const { performance } = require('perf_hooks')
class MetricHelper {
constructor({ metricInstance }, { category, serviceFamily, name }) {
if (metricInstance) {
this.metricInstance = metricInstance
this.serviceRequestCounter = metricInstance.createNumRequestCounter({
category,
serviceFamily,
name,
})
} else {
this.metricInstance = undefined
this.serviceRequestCounter = undefined
}
}
static create({ metricInstance, ServiceClass }) {
const { category, serviceFamily, name } = ServiceClass
return new this({ metricInstance }, { category, serviceFamily, name })
}
startRequest() {
const { metricInstance, serviceRequestCounter } = this
const requestStartTime = performance.now()
return {
noteResponseSent() {
if (metricInstance) {
const elapsedTime = performance.now() - requestStartTime
metricInstance.noteResponseTime(elapsedTime)
}
if (serviceRequestCounter) {
serviceRequestCounter.inc()
}
},
}
}
}
module.exports = { MetricHelper }

View File

@@ -2,14 +2,16 @@
const camelcase = require('camelcase')
const emojic = require('emojic')
const Joi = require('joi')
const Joi = require('@hapi/joi')
const queryString = require('query-string')
const log = require('../server/log')
const BaseService = require('./base')
const {
serverHasBeenUpSinceResourceCached,
setCacheHeadersForStaticResource,
} = require('./cache-headers')
const { isValidCategory } = require('./categories')
const { MetricHelper } = require('./metric-helper')
const { isValidRoute, prepareRoute, namedParamsForMatch } = require('./route')
const trace = require('./trace')
@@ -62,11 +64,15 @@ module.exports = function redirector(attrs) {
return route
}
static register({ camp, requestCounter }) {
const { regex, captureNames } = prepareRoute(this.route)
static register({ camp, metricInstance }, { rasterUrl }) {
const { regex, captureNames } = prepareRoute({
...this.route,
withPng: Boolean(rasterUrl),
})
const serviceRequestCounter = this._createServiceRequestCounter({
requestCounter,
const metricHelper = MetricHelper.create({
metricInstance,
ServiceClass: this,
})
camp.route(regex, async (queryParams, match, end, ask) => {
@@ -77,6 +83,8 @@ module.exports = function redirector(attrs) {
return
}
const metricHandle = metricHelper.startRequest()
const namedParams = namedParamsForMatch(captureNames, match, this)
trace.logTrace(
'inbound',
@@ -103,20 +111,27 @@ module.exports = function redirector(attrs) {
}
// The final capture group is the extension.
const format = match.slice(-1)[0]
const redirectUrl = `${targetPath}.${format}${urlSuffix}`
const format = (match.slice(-1)[0] || '.svg').replace(/^\./, '')
const redirectUrl = `${
format === 'png' ? rasterUrl : ''
}${targetPath}.${format}${urlSuffix}`
trace.logTrace('outbound', emojic.shield, 'Redirect URL', redirectUrl)
ask.res.statusCode = 301
ask.res.setHeader('Location', redirectUrl)
try {
ask.res.statusCode = 301
ask.res.setHeader('Location', redirectUrl)
} catch (e) {
log.error(new Error(`An invalid URL in '${this.name}' redirector.`))
ask.res.statusCode = 302
ask.res.setHeader('Location', '/badge/badge-inaccessible-lightgray')
}
// To avoid caching mistakes for a long time, and to make this simpler
// to reason about, use the same cache semantics as the static badge.
setCacheHeadersForStaticResource(ask.res)
ask.res.end()
serviceRequestCounter.inc()
metricHandle.noteResponseSent()
})
}
}

View File

@@ -1,9 +1,9 @@
'use strict'
const Camp = require('camp')
const got = require('got')
const portfinder = require('portfinder')
const { expect } = require('chai')
const got = require('../got-test-client')
const redirector = require('./redirector')
describe('Redirector', function() {
@@ -75,7 +75,10 @@ describe('Redirector', function() {
transformPath,
dateAdded,
})
ServiceClass.register({ camp }, {})
ServiceClass.register(
{ camp },
{ rasterUrl: 'http://raster.example.test' }
)
})
it('should redirect as configured', async function() {
@@ -90,7 +93,20 @@ describe('Redirector', function() {
expect(headers.location).to.equal('/new/service/hello-world.svg')
})
it('should preserve the extension', async function() {
// https://github.com/badges/shields/issues/4013
it('should temporarily redirect to a badge with message "inaccesible" when redirect URL is invalid (contains invalid characters)', async function() {
const { statusCode, headers } = await got(
`${baseUrl}/very/old/service/hello\nworld.svg`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(302)
expect(headers.location).to.equal('/badge/badge-inaccessible-lightgray')
})
it('should redirect raster extensions to the canonical path as configured', async function() {
const { statusCode, headers } = await got(
`${baseUrl}/very/old/service/hello-world.png`,
{
@@ -99,7 +115,9 @@ describe('Redirector', function() {
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal('/new/service/hello-world.png')
expect(headers.location).to.equal(
'http://raster.example.test/new/service/hello-world.png'
)
})
it('should forward the query params', async function() {

View File

@@ -1,6 +1,7 @@
'use strict'
const Joi = require('joi')
const escapeStringRegexp = require('escape-string-regexp')
const Joi = require('@hapi/joi')
const pathToRegexp = require('path-to-regexp')
function makeFullUrl(base, partialUrl) {
@@ -13,7 +14,7 @@ const isValidRoute = Joi.object({
.required(),
pattern: Joi.string().allow(''),
format: Joi.string(),
capture: Joi.alternatives().when('format', {
capture: Joi.alternatives().conditional('format', {
is: Joi.string().required(),
then: Joi.array().items(Joi.string().required()),
}),
@@ -26,18 +27,17 @@ function assertValidRoute(route, message = undefined) {
Joi.assert(route, isValidRoute, message)
}
function prepareRoute({ base, pattern, format, capture }) {
function prepareRoute({ base, pattern, format, capture, withPng }) {
const extensionRegex = ['', '.svg', '.json']
.concat(withPng ? ['.png'] : [])
.map(escapeStringRegexp)
.join('|')
let regex, captureNames
if (pattern === undefined) {
regex = new RegExp(
`^${makeFullUrl(base, format)}\\.(svg|png|gif|jpg|json)$`
)
regex = new RegExp(`^${makeFullUrl(base, format)}(${extensionRegex})$`)
captureNames = capture || []
} else {
const fullPattern = `${makeFullUrl(
base,
pattern
)}.:ext(svg|png|gif|jpg|json)`
const fullPattern = `${makeFullUrl(base, pattern)}:ext(${extensionRegex})`
const keys = []
regex = pathToRegexp(fullPattern, keys, {
strict: true,
@@ -55,9 +55,7 @@ function namedParamsForMatch(captureNames = [], match, ServiceClass) {
if (captureNames.length !== captures.length) {
throw new Error(
`Service ${
ServiceClass.name
} declares incorrect number of named params ` +
`Service ${ServiceClass.name} declares incorrect number of named params ` +
`(expected ${captures.length}, got ${captureNames.length})`
)
}
@@ -71,8 +69,8 @@ function namedParamsForMatch(captureNames = [], match, ServiceClass) {
function getQueryParamNames({ queryParamSchema }) {
if (queryParamSchema) {
const { children, renames = [] } = Joi.describe(queryParamSchema)
return Object.keys(children).concat(renames.map(({ from }) => from))
const { keys, renames = [] } = queryParamSchema.describe()
return Object.keys(keys).concat(renames.map(({ from }) => from))
} else {
return []
}

View File

@@ -1,7 +1,7 @@
'use strict'
const { expect } = require('chai')
const Joi = require('joi')
const Joi = require('@hapi/joi')
const { test, given, forCases } = require('sazerac')
const {
prepareRoute,
@@ -19,13 +19,7 @@ describe('Route helpers', function() {
const regexExec = str => regex.exec(str)
test(regexExec, () => {
forCases([
given('/foo/bar.bar.bar.zip'),
given('/foo/bar/bar.svg'),
// This is a valid example with the wrong extension separator, to
// test that we only accept a `.`.
given('/foo/bar.bar.bar_svg'),
]).expect(null)
given('/foo/bar/bar.svg').expect(null)
})
const namedParams = str =>
@@ -33,30 +27,25 @@ describe('Route helpers', function() {
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({ namedParamA: 'bar.bar.bar' })
// This pattern catches bugs related to escaping the extension separator.
given('/foo/bar.bar.bar_svg').expect({ namedParamA: 'bar.bar.bar_svg' })
given('/foo/bar.bar.bar.zip').expect({ namedParamA: 'bar.bar.bar.zip' })
})
})
context('A `format` with a named param is declared', function() {
const { regex, captureNames } = prepareRoute({
base: 'foo',
format: '([^/]+)',
format: '([^/]+?)',
capture: ['namedParamA'],
})
const regexExec = str => regex.exec(str)
test(regexExec, () => {
forCases([
given('/foo/bar.bar.bar.zip'),
given('/foo/bar/bar.svg'),
// This is a valid example with the wrong extension separator, to
// test that we only accept a `.`.
given('/foo/bar.bar.bar_svg'),
]).expect(null)
given('/foo/bar/bar.svg').expect(null)
})
const namedParams = str =>
@@ -64,11 +53,12 @@ describe('Route helpers', function() {
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({ namedParamA: 'bar.bar.bar' })
// This pattern catches bugs related to escaping the extension separator.
given('/foo/bar.bar.bar_svg').expect({ namedParamA: 'bar.bar.bar_svg' })
given('/foo/bar.bar.bar.zip').expect({ namedParamA: 'bar.bar.bar.zip' })
})
})
@@ -83,9 +73,6 @@ describe('Route helpers', function() {
test(namedParams, () => {
forCases([
given('/foo/bar.bar.bar.svg'),
given('/foo/bar.bar.bar.png'),
given('/foo/bar.bar.bar.gif'),
given('/foo/bar.bar.bar.jpg'),
given('/foo/bar.bar.bar.json'),
]).expect({})
})

View File

@@ -1,13 +1,13 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
// This should be kept in sync with the schema in
// `frontend/lib/service-definitions/service-definition-prop-types.js`.
// `frontend/lib/service-definitions/index.ts`.
const arrayOfStrings = Joi.array()
.items(Joi.string())
.allow([])
.min(0)
.required()
const objectOfKeyValues = Joi.object()
@@ -66,6 +66,7 @@ const serviceDefinitionExport = Joi.object({
Joi.object({
id: Joi.string().required(),
name: Joi.string().required(),
keywords: arrayOfStrings,
})
)
.required(),

View File

@@ -1,7 +1,7 @@
'use strict'
const emojic = require('emojic')
const Joi = require('joi')
const Joi = require('@hapi/joi')
const trace = require('./trace')
function validate(
@@ -16,16 +16,15 @@ function validate(
data,
schema
) {
if (!schema || !schema.isJoi) {
if (!schema || !Joi.isSchema(schema)) {
throw Error('A Joi schema is required')
}
const options = allowAndStripUnknownKeys
? {
allowUnknown: true,
stripUnknown: true,
}
: undefined
const { error, value } = Joi.validate(data, schema, options)
const options = { abortEarly: false }
if (allowAndStripUnknownKeys) {
options['allowUnknown'] = true
options['stripUnknown'] = true
}
const { error, value } = schema.validate(data, options)
if (error) {
trace.logTrace(
'validate',

View File

@@ -1,6 +1,6 @@
'use strict'
const Joi = require('joi')
const Joi = require('@hapi/joi')
const { expect } = require('chai')
const sinon = require('sinon')
const trace = require('./trace')
@@ -72,7 +72,7 @@ describe('validate', function() {
} catch (e) {
expect(e).to.be.an.instanceof(InvalidParameter)
expect(e.message).to.equal(
'Invalid Parameter: child "requiredString" fails because ["requiredString" must be a string]'
'Invalid Parameter: "requiredString" must be a string'
)
expect(e.prettyMessage).to.equal(prettyErrorMessage)
}
@@ -80,7 +80,7 @@ describe('validate', function() {
'validate',
sinon.match.string,
traceErrorMessage,
'child "requiredString" fails because ["requiredString" must be a string]'
'"requiredString" must be a string'
)
})
@@ -98,7 +98,7 @@ describe('validate', function() {
} catch (e) {
expect(e).to.be.an.instanceof(InvalidParameter)
expect(e.message).to.equal(
'Invalid Parameter: child "requiredString" fails because ["requiredString" must be a string]'
'Invalid Parameter: "requiredString" must be a string'
)
expect(e.prettyMessage).to.equal(
`${prettyErrorMessage}: requiredString`

6
core/got-test-client.js Normal file
View File

@@ -0,0 +1,6 @@
'use strict'
const got = require('got')
// https://github.com/nock/nock/issues/1523
module.exports = got.extend({ retry: 0 })

View File

@@ -1,6 +1,5 @@
'use strict'
const Raven = require('raven')
const throttle = require('lodash.throttle')
const Sentry = require('@sentry/node')
const listeners = []
@@ -30,22 +29,11 @@ module.exports = function log(...msg) {
console.log(d, ...msg)
}
const throttledConsoleError = throttle(console.error, 10000, {
trailing: false,
})
module.exports.error = function error(...msg) {
module.exports.error = function error(err) {
const d = date()
listeners.forEach(f => f(d, ...msg))
Raven.captureException(msg, sendErr => {
if (sendErr) {
throttledConsoleError(
'Failed to send captured exception to Sentry',
sendErr.message
)
}
})
console.error(d, ...msg)
listeners.forEach(f => f(d, err))
Sentry.captureException(err)
console.error(d, err)
}
module.exports.addListener = function addListener(func) {

View File

@@ -1,63 +0,0 @@
'use strict'
const chai = require('chai')
const expect = chai.expect
const sinon = require('sinon')
const sinonChai = require('sinon-chai')
const Raven = require('raven')
chai.use(sinonChai)
function requireUncached(module) {
delete require.cache[require.resolve(module)]
return require(module)
}
describe('log', function() {
describe('error', function() {
before(function() {
this.clock = sinon.useFakeTimers()
sinon.stub(Raven, 'captureException').callsFake((e, callback) => {
callback(new Error(`Cannot send message "${e}" to Sentry.`))
})
// we have to create a spy before requiring 'error' function
sinon.spy(console, 'error')
this.error = requireUncached('./log').error
})
after(function() {
this.clock.restore()
console.error.restore()
Raven.captureException.restore()
})
it('should throttle errors from Raven client', function() {
this.error('test error 1')
this.error('test error 2')
this.error('test error 3')
this.clock.tick(11000)
this.error('test error 4')
this.error('test error 5')
expect(console.error).to.be.calledWithExactly(
'Failed to send captured exception to Sentry',
'Cannot send message "test error 1" to Sentry.'
)
expect(console.error).to.not.be.calledWithExactly(
'Failed to send captured exception to Sentry',
'Cannot send message "test error 2" to Sentry.'
)
expect(console.error).to.not.be.calledWithExactly(
'Failed to send captured exception to Sentry',
'Cannot send message "test error 3" to Sentry.'
)
expect(console.error).to.be.calledWithExactly(
'Failed to send captured exception to Sentry',
'Cannot send message "test error 4" to Sentry.'
)
expect(console.error).to.not.be.calledWithExactly(
'Failed to send captured exception to Sentry',
'Cannot send message "test error 5" to Sentry.'
)
})
})
})

View File

@@ -1,6 +1,6 @@
'use strict'
const serverSecrets = require('../../lib/server-secrets')
const config = require('config').util.toObject()
const secretIsValid = require('./secret-is-valid')
const RateLimit = require('./rate-limit')
const log = require('./log')
@@ -16,9 +16,11 @@ function secretInvalid(req, res) {
return false
}
function setRoutes({ rateLimit }, server) {
function setRoutes({ rateLimit }, { server, metricInstance }) {
const ipRateLimit = new RateLimit({
whitelist: /^192\.30\.252\.\d+$/, // Whitelist GitHub IPs.
// Exclude IPs for GitHub Camo, determined experimentally by running e.g.
// `curl --insecure -u ":shields-secret" https://s0.shields-server.com/sys/rate-limit`
whitelist: /^(?:192\.30\.252\.\d+)|(?:140\.82\.115\.\d+)$/,
})
const badgeTypeRateLimit = new RateLimit({ maxHitsPerPeriod: 3000 })
const refererRateLimit = new RateLimit({
@@ -44,12 +46,15 @@ function setRoutes({ rateLimit }, server) {
const referer = req.headers['referer']
if (ipRateLimit.isBanned(ip, req, res)) {
metricInstance.noteRateLimitExceeded('ip')
return
}
if (badgeTypeRateLimit.isBanned(badgeType, req, res)) {
metricInstance.noteRateLimitExceeded('badge_type')
return
}
if (refererRateLimit.isBanned(referer, req, res)) {
metricInstance.noteRateLimitExceeded('referrer')
return
}
}
@@ -58,7 +63,7 @@ function setRoutes({ rateLimit }, server) {
})
server.get('/sys/network', (req, res) => {
res.json({ ips: serverSecrets.shields_ips })
res.json({ ips: config.public.shields_ips })
})
server.ws('/sys/logs', socket => {

View File

@@ -1,16 +1,65 @@
'use strict'
const decamelize = require('decamelize')
const prometheus = require('prom-client')
module.exports = class PrometheusMetrics {
constructor() {
this.register = new prometheus.Registry()
this.requestCounter = new prometheus.Counter({
name: 'service_requests_total',
help: 'Total service requests',
labelNames: ['category', 'family', 'service'],
registers: [this.register],
})
this.counters = {
numRequests: new prometheus.Counter({
name: 'service_requests_total',
help: 'Total service requests',
labelNames: ['category', 'family', 'service'],
registers: [this.register],
}),
responseTime: new prometheus.Histogram({
name: 'service_response_millis',
help: 'Service response time in milliseconds',
// 250 ms increments up to 2 seconds, then 500 ms increments up to 8
// seconds, then 1 second increments up to 15 seconds.
buckets: [
250,
500,
750,
1000,
1250,
1500,
1750,
2000,
2250,
2500,
2750,
3000,
3250,
3500,
3750,
4000,
4500,
5000,
5500,
6000,
6500,
7000,
7500,
8000,
9000,
10000,
11000,
12000,
13000,
14000,
15000,
],
registers: [this.register],
}),
rateLimitExceeded: new prometheus.Counter({
name: 'rate_limit_exceeded_total',
help: 'Count of rate limit exceeded by type',
labelNames: ['rate_limit_type'],
registers: [this.register],
}),
}
}
async initialize(server) {
@@ -30,4 +79,20 @@ module.exports = class PrometheusMetrics {
this.interval = undefined
}
}
/**
* @returns {object} `{ inc() {} }`.
*/
createNumRequestCounter({ category, serviceFamily, name }) {
const service = decamelize(name)
return this.counters.numRequests.labels(category, serviceFamily, service)
}
noteResponseTime(responseTime) {
return this.counters.responseTime.observe(responseTime)
}
noteRateLimitExceeded(rateLimitType) {
return this.counters.rateLimitExceeded.labels(rateLimitType).inc()
}
}

View File

@@ -1,10 +1,9 @@
'use strict'
const { expect } = require('chai')
// https://github.com/nock/nock/issues/1523
const got = require('got').extend({ retry: 0 })
const Camp = require('camp')
const portfinder = require('portfinder')
const got = require('../got-test-client')
const Metrics = require('./prometheus-metrics')
describe('Prometheus metrics route', function() {

View File

@@ -2,13 +2,6 @@
const serverSecrets = require('../../lib/server-secrets')
function secretIsValid(secret = '') {
return (
serverSecrets.shields_secret &&
constEq(secret, serverSecrets.shields_secret)
)
}
function constEq(a, b) {
if (a.length !== b.length) {
return false
@@ -20,4 +13,9 @@ function constEq(a, b) {
return zero === 0
}
module.exports = secretIsValid
module.exports = function secretIsValid(secret = '') {
return (
serverSecrets.shields_secret &&
constEq(secret, serverSecrets.shields_secret)
)
}

View File

@@ -1,10 +1,12 @@
'use strict'
/**
* @module
*/
const fs = require('fs')
const path = require('path')
const url = require('url')
const bytes = require('bytes')
const Joi = require('joi')
const Joi = require('@hapi/joi')
const Camp = require('camp')
const makeBadge = require('../../gh-badges/lib/make-badge')
const GithubConstellation = require('../../services/github/github-constellation')
@@ -16,7 +18,7 @@ const {
clearRequestCache,
} = require('../base-service/legacy-request-handler')
const { clearRegularUpdateCache } = require('../legacy/regular-update')
const { staticBadgeUrl } = require('../badge-urls/make-badge-url')
const { rasterRedirectUrl } = require('../badge-urls/make-badge-url')
const log = require('./log')
const sysMonitor = require('./monitor')
const PrometheusMetrics = require('./prometheus-metrics')
@@ -24,11 +26,6 @@ const PrometheusMetrics = require('./prometheus-metrics')
const optionalUrl = Joi.string().uri({ scheme: ['http', 'https'] })
const requiredUrl = optionalUrl.required()
const notFound = fs.readFileSync(
path.resolve(__dirname, 'error-pages', '404.html'),
'utf-8'
)
const publicConfigSchema = Joi.object({
bind: {
port: Joi.number().port(),
@@ -52,6 +49,7 @@ const publicConfigSchema = Joi.object({
cert: Joi.string(),
},
redirectUrl: optionalUrl,
rasterUrl: optionalUrl,
cors: {
allowedOrigin: Joi.array()
.items(optionalUrl)
@@ -59,7 +57,6 @@ const publicConfigSchema = Joi.object({
},
persistence: {
dir: Joi.string().required(),
redisUrl: optionalUrl,
},
services: {
github: {
@@ -101,16 +98,34 @@ const privateConfigSchema = Joi.object({
nexus_user: Joi.string(),
nexus_pass: Joi.string(),
npm_token: Joi.string(),
redis_url: Joi.string().uri({ scheme: ['redis', 'rediss'] }),
sentry_dsn: Joi.string(),
shields_ips: Joi.array().items(Joi.string().ip()),
shields_secret: Joi.string(),
sl_insight_userUuid: Joi.string(),
sl_insight_apiToken: Joi.string(),
sonarqube_token: Joi.string(),
twitch_client_id: Joi.string(),
twitch_client_secret: Joi.string(),
wheelmap_token: Joi.string(),
}).required()
module.exports = class Server {
/**
* The Server is based on the web framework Scoutcamp. It creates
* an http server, sets up helpers for token persistence and monitoring.
* Then it loads all the services, injecting dependencies as it
* asks each one to register its route with Scoutcamp.
*/
class Server {
/**
* Badge Server Constructor
*
* @param {object} config Configuration object read from config yaml files
* by https://www.npmjs.com/package/config and validated against
* publicConfigSchema and privateConfigSchema
* @see https://github.com/badges/shields/blob/master/doc/production-hosting.md#configuration
* @see https://github.com/badges/shields/blob/master/doc/server-secrets.md
*/
constructor(config) {
const publicConfig = Joi.attempt(config.public, publicConfigSchema)
let privateConfig
@@ -132,9 +147,10 @@ module.exports = class Server {
this.githubConstellation = new GithubConstellation({
persistence: publicConfig.persistence,
service: publicConfig.services.github,
private: privateConfig,
})
if (publicConfig.metrics.prometheus.enabled) {
this.metrics = new PrometheusMetrics()
this.metricInstance = new PrometheusMetrics()
}
}
@@ -160,77 +176,119 @@ module.exports = class Server {
})
}
/**
* Set up Scoutcamp routes for 404/not found responses
*/
registerErrorHandlers() {
const { camp } = this
const { camp, config } = this
const {
public: { rasterUrl },
} = config
camp.notfound(/\.(svg|png|gif|jpg|json)/, (query, match, end, request) => {
camp.route(/\.(gif|jpg)$/, (query, match, end, request) => {
const [, format] = match
const svg = makeBadge({
text: ['404', 'badge not found'],
color: 'red',
format,
})
makeSend(format, request.res, end)(svg)
})
camp.notfound(/.*/, (query, match, end, request) => {
end(notFound)
})
}
registerServices() {
const { config, camp } = this
const { apiProvider: githubApiProvider } = this.githubConstellation
const { requestCounter } = this.metrics || {}
loadServiceClasses().forEach(serviceClass =>
serviceClass.register(
{ camp, handleRequest, githubApiProvider, requestCounter },
{
handleInternalErrors: config.public.handleInternalErrors,
cacheHeaders: config.public.cacheHeaders,
profiling: config.public.profiling,
fetchLimitBytes: bytes(config.public.fetchLimit),
}
makeSend('svg', request.res, end)(
makeBadge({
text: ['410', `${format} no longer available`],
color: 'lightgray',
format: 'svg',
})
)
)
})
if (!rasterUrl) {
camp.route(/\.png$/, (query, match, end, request) => {
makeSend('svg', request.res, end)(
makeBadge({
text: ['404', 'raster badges not available'],
color: 'lightgray',
format: 'svg',
})
)
})
}
camp.notfound(/(\.svg|\.json|)$/, (query, match, end, request) => {
const [, extension] = match
const format = (extension || '.svg').replace(/^\./, '')
makeSend(format, request.res, end)(
makeBadge({
text: ['404', 'badge not found'],
color: 'red',
format,
})
)
})
}
/**
* Set up a couple of redirects:
* One for the raster badges.
* Another to redirect the base URL /
* (we use this to redirect {@link https://img.shields.io/}
* to {@link https://shields.io/} )
*/
registerRedirects() {
const { config, camp } = this
const {
public: { rasterUrl, redirectUrl },
} = config
// Any badge, old version. This route must be registered last.
camp.route(/^\/([^/]+)\/(.+).png$/, (queryParams, match, end, ask) => {
const [, label, message] = match
const { color } = queryParams
if (rasterUrl) {
// Redirect to the raster server for raster versions of modern badges.
camp.route(/\.png$/, (queryParams, match, end, ask) => {
ask.res.statusCode = 301
ask.res.setHeader(
'Location',
rasterRedirectUrl({ rasterUrl }, ask.req.url)
)
const redirectUrl = staticBadgeUrl({
label,
message,
// Fixes https://github.com/badges/shields/issues/3260
color: color ? color.toString() : undefined,
format: 'png',
const cacheDuration = (30 * 24 * 3600) | 0 // 30 days.
ask.res.setHeader('Cache-Control', `max-age=${cacheDuration}`)
ask.res.end()
})
}
ask.res.statusCode = 301
ask.res.setHeader('Location', redirectUrl)
// The redirect is permanent.
const cacheDuration = (365 * 24 * 3600) | 0 // 1 year
ask.res.setHeader('Cache-Control', `max-age=${cacheDuration}`)
ask.res.end()
})
if (config.public.redirectUrl) {
if (redirectUrl) {
camp.route(/^\/$/, (data, match, end, ask) => {
ask.res.statusCode = 302
ask.res.setHeader('Location', config.public.redirectUrl)
ask.res.setHeader('Location', redirectUrl)
ask.res.end()
})
}
}
/**
* Iterate all the service classes defined in /services,
* load each service and register a Scoutcamp route for each service.
*/
registerServices() {
const { config, camp, metricInstance } = this
const { apiProvider: githubApiProvider } = this.githubConstellation
loadServiceClasses().forEach(serviceClass =>
serviceClass.register(
{ camp, handleRequest, githubApiProvider, metricInstance },
{
handleInternalErrors: config.public.handleInternalErrors,
cacheHeaders: config.public.cacheHeaders,
profiling: config.public.profiling,
fetchLimitBytes: bytes(config.public.fetchLimit),
rasterUrl: config.public.rasterUrl,
private: config.private,
}
)
)
}
/**
* Start the HTTP server:
* Bootstrap Scoutcamp,
* Register handlers,
* Start listening for requests on this.baseUrl()
*/
async start() {
const {
bind: { port, address: hostname },
@@ -250,20 +308,30 @@ module.exports = class Server {
key,
}))
this.cleanupMonitor = sysMonitor.setRoutes({ rateLimit }, camp)
const { metricInstance } = this
this.cleanupMonitor = sysMonitor.setRoutes(
{ rateLimit },
{ server: camp, metricInstance }
)
const { githubConstellation, metrics } = this
const { githubConstellation } = this
githubConstellation.initialize(camp)
if (metrics) {
metrics.initialize(camp)
if (metricInstance) {
metricInstance.initialize(camp)
}
const { apiProvider: githubApiProvider } = this.githubConstellation
suggest.setRoutes(allowedOrigin, githubApiProvider, camp)
// https://github.com/badges/shields/issues/3273
camp.handle((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*')
next()
})
this.registerErrorHandlers()
this.registerServices()
this.registerRedirects()
this.registerServices()
await new Promise(resolve => camp.on('listening', () => resolve()))
}
@@ -279,6 +347,9 @@ module.exports = class Server {
this.constructor.resetGlobalState()
}
/**
* Stop the HTTP server and clean up helpers
*/
async stop() {
if (this.camp) {
await new Promise(resolve => this.camp.close(resolve))
@@ -295,8 +366,10 @@ module.exports = class Server {
this.githubConstellation = undefined
}
if (this.metrics) {
this.metrics.stop()
if (this.metricInstance) {
this.metricInstance.stop()
}
}
}
module.exports = Server

View File

@@ -1,15 +1,9 @@
'use strict'
const fs = require('fs')
const path = require('path')
const { expect } = require('chai')
// https://github.com/nock/nock/issues/1523
const got = require('got').extend({ retry: 0 })
const isPng = require('is-png')
const isSvg = require('is-svg')
const sinon = require('sinon')
const portfinder = require('portfinder')
const svg2img = require('../../gh-badges/lib/svg-to-img')
const got = require('../got-test-client')
const { createTestServer } = require('./in-process-server-test-helpers')
describe('The server', function() {
@@ -38,12 +32,36 @@ describe('The server', function() {
.and.to.include('apple')
})
it('should produce colorscheme PNG badges', async function() {
const { statusCode, body } = await got(`${baseUrl}:fruit-apple-green.png`, {
encoding: null,
it('should redirect colorscheme PNG badges as configured', async function() {
const { statusCode, headers } = await got(
`${baseUrl}:fruit-apple-green.png`,
{
followRedirect: false,
}
)
expect(statusCode).to.equal(301)
expect(headers.location).to.equal(
'http://raster.example.test/:fruit-apple-green.png'
)
})
it('should redirect modern PNG badges as configured', async function() {
const { statusCode, headers } = await got(`${baseUrl}npm/v/express.png`, {
followRedirect: false,
})
expect(statusCode).to.equal(301)
expect(headers.location).to.equal(
'http://raster.example.test/npm/v/express.png'
)
})
it('should produce json badges', async function() {
const { statusCode, body, headers } = await got(
`${baseUrl}npm/v/express.json`
)
expect(statusCode).to.equal(200)
expect(body).to.satisfy(isPng)
expect(headers['content-type']).to.equal('application/json')
expect(() => JSON.parse(body)).not.to.throw()
})
it('should preserve label case', async function() {
@@ -100,13 +118,16 @@ describe('The server', function() {
.and.to.include('badge not found')
})
it('should return the 404 html page for rando links', async function() {
it('should return the 404 badge page for rando links', async function() {
const { statusCode, body } = await got(
`${baseUrl}this/is/most/definitely/not/a/badge.js`,
{ throwHttpErrors: false }
)
expect(statusCode).to.equal(404)
expect(body).to.include('blood, toil, tears and sweat')
expect(body)
.to.satisfy(isSvg)
.and.to.include('404')
.and.to.include('badge not found')
})
it('should redirect the root as configured', async function() {
@@ -116,31 +137,24 @@ describe('The server', function() {
expect(statusCode).to.equal(302)
// This value is set in `config/test.yml`
expect(headers.location).to.equal('http://badge-server.example.com')
expect(headers.location).to.equal('http://frontend.example.test')
})
context('with svg2img error', function() {
const expectedError = fs.readFileSync(
path.resolve(__dirname, 'error-pages', '500.html')
)
it('should return the 410 badge for obsolete formats', async function() {
const { statusCode, body } = await got(`${baseUrl}npm/v/express.jpg`, {
throwHttpErrors: false,
})
// TODO It would be nice if this were 404 or 410.
expect(statusCode).to.equal(200)
expect(body)
.to.satisfy(isSvg)
.and.to.include('410')
.and.to.include('jpg no longer available')
})
let toBufferStub
beforeEach(function() {
toBufferStub = sinon
.stub(svg2img._imageMagick.prototype, 'toBuffer')
.callsArgWith(1, Error('whoops'))
})
afterEach(function() {
toBufferStub.restore()
})
it('should emit the 500 message', async function() {
const { statusCode, body } = await got(
`${baseUrl}:some_new-badge-green.png`
)
// This emits status code 200, though 500 would be preferable.
expect(statusCode).to.equal(200)
expect(body).to.include(expectedError)
})
it('should return cors header for the request', async function() {
const { statusCode, headers } = await got(`${baseUrl}npm/v/express.svg`)
expect(statusCode).to.equal(200)
expect(headers['access-control-allow-origin']).to.equal('*')
})
})

View File

@@ -15,6 +15,11 @@
// Run tests on a given instance:
// SKIP_INTERCEPTED=TRUE TESTED_SERVER_URL=https://test.shields.io npm run test:services --
//
// Run tests with given number of retries and backoff (in milliseconds):
// RETRY_COUNT=3 RETRY_BACKOFF=100 npm run test:services --
// Retry option documentation:
// https://github.com/IcedFrisby/IcedFrisby/blob/master/API.md#retrycount-backoff
//
// Service tests are run in CI in two cases: scheduled builds and pull
// requests. The scheduled builds run _all_ the service tests, whereas the
// pull requests run service tests designated in the PR title. In this way,
@@ -59,6 +64,9 @@ const Runner = require('./runner')
require('../unhandled-rejection.spec')
const retry = {}
retry.count = parseInt(process.env.RETRY_COUNT) || 0
retry.backoff = parseInt(process.env.RETRY_BACKOFF) || 0
let baseUrl, server
if (process.env.TESTED_SERVER_URL) {
baseUrl = process.env.TESTED_SERVER_URL
@@ -77,7 +85,7 @@ if (process.env.TESTED_SERVER_URL) {
}
const skipIntercepted = envFlag(process.env.SKIP_INTERCEPTED, false)
const runner = new Runner({ baseUrl, skipIntercepted })
const runner = new Runner({ baseUrl, skipIntercepted, retry })
runner.prepare()
// The server's request cache causes side effects between tests.

View File

@@ -1,16 +1,24 @@
'use strict'
/**
* @module
*/
const caller = require('caller')
const BaseService = require('../base-service/base')
const ServiceTester = require('./service-tester')
// Automatically create a ServiceTester.
//
// When run from e.g. `gem-rank.tester.js`, this will create a tester that
// attaches to the service found in `gem-rank.service.js`.
//
// This can't be used for `.service.js` files which export more than one
// service.
/**
* Automatically create a ServiceTester.
*
* When run from e.g. `gem-rank.tester.js`, this will create a tester that
* attaches to the service found in `gem-rank.service.js`.
*
* This can't be used for `.service.js` files which export more than one
* service.
*
* @returns {module:core/service-test-runner/service-tester~ServiceTester}
* ServiceTester instance
*/
function createServiceTester() {
const servicePath = caller().replace('.tester.js', '.service.js')
const ServiceClass = require(servicePath)

View File

@@ -1,12 +1,20 @@
'use strict'
/**
* @module
*/
const Joi = require('joi')
const Joi = require('@hapi/joi')
const { expect } = require('chai')
// based on https://github.com/paulmelnikow/icedfrisby-nock/blob/master/icedfrisby-nock.js
// can be used to wrap the original "icedfrisby-nock" with additional functionality:
// - check if a request was intercepted
// - set expectations on the badge JSON response
/**
* Factory which wraps an "icedfrisby-nock" with some additional functionality:
* - check if a request was intercepted
* - set expectations on the badge JSON response
*
* @param {Function} superclass class to extend
* @see https://github.com/paulmelnikow/icedfrisby-nock/blob/master/icedfrisby-nock.js
* @returns {Function} wrapped class
*/
const factory = superclass =>
class IcedFrisbyNock extends superclass {
constructor(message) {
@@ -44,12 +52,23 @@ const factory = superclass =>
}
static _expectField(json, name, expected) {
if (typeof expected === 'string') {
if (typeof expected === 'undefined') return
if (typeof expected === 'string' || typeof expected === 'number') {
expect(json[name], `${name} mismatch`).to.equal(expected)
} else if (Array.isArray(expected)) {
expect(json[name], `${name} mismatch`).to.deep.equal(expected)
} else if (typeof expected === 'object') {
} else if (Joi.isSchema(expected)) {
Joi.attempt(json[name], expected, `${name} mismatch:`)
} else if (expected instanceof RegExp) {
Joi.attempt(
json[name],
Joi.string().regex(expected),
`${name} mismatch:`
)
} else {
throw new Error(
"'expected' must be a string, a number, a regex, an array or a Joi schema"
)
}
}
}

View File

@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const { URL, format: urlFormat } = require('url')
@@ -60,6 +63,14 @@ function _inferPullRequestFromCircleEnv(env) {
return parseGithubPullRequestUrl(env.CI_PULL_REQUEST)
}
/**
* When called inside a CI build, infer the details
* of a pull request from the environment variables.
*
* @param {object} [env=process.env] Environment variables
* @returns {module:core/service-test-runner/infer-pull-request~PullRequest}
* Pull Request
*/
function inferPullRequest(env = process.env) {
if (env.TRAVIS) {
return _inferPullRequestFromTravisEnv(env)
@@ -76,6 +87,17 @@ function inferPullRequest(env = process.env) {
}
}
/**
* Pull Request
*
* @typedef PullRequest
* @property {string} pr.baseUrl (returned for travis CI only)
* @property {string} owner
* @property {string} repo
* @property {string} pullRequest PR/issue number
* @property {string} slug owner/repo/#pullRequest
*/
module.exports = {
parseGithubPullRequestUrl,
parseGithubRepoSlug,

View File

@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const { loadTesters } = require('../base-service/loader')
@@ -6,9 +9,10 @@ const { loadTesters } = require('../base-service/loader')
* Load a collection of ServiceTester objects and register them with Mocha.
*/
class Runner {
constructor({ baseUrl, skipIntercepted }) {
constructor({ baseUrl, skipIntercepted, retry }) {
this.baseUrl = baseUrl
this.skipIntercepted = skipIntercepted
this.retry = retry
}
/**
@@ -36,7 +40,7 @@ class Runner {
/**
* Limit the test run to the specified services.
*
* @param services An array of service id prefixes to run
* @param {string[]} services An array of service id prefixes to run
*/
only(services) {
const normalizedServices = new Set(services.map(v => v.toLowerCase()))
@@ -64,8 +68,8 @@ class Runner {
* Register the tests with Mocha.
*/
toss() {
const { testers, baseUrl, skipIntercepted } = this
testers.forEach(tester => tester.toss({ baseUrl, skipIntercepted }))
const { testers, baseUrl, skipIntercepted, retry } = this
testers.forEach(tester => tester.toss({ baseUrl, skipIntercepted, retry }))
}
}
module.exports = Runner

View File

@@ -1,4 +1,7 @@
'use strict'
/**
* @module
*/
const emojic = require('emojic')
const trace = require('../base-service/trace')
@@ -10,13 +13,21 @@ const frisby = require('./icedfrisby-shields')(
/**
* Encapsulate a suite of tests. Create new tests using create() and register
* them with Mocha using toss().
*
* @see https://github.com/badges/shields/blob/master/doc/service-tests.md
*/
class ServiceTester {
/**
* @param attrs { id, title, pathPrefix } The `id` is used to specify which
* tests to run from the CLI or pull requests. The `title` prints in the
* Mocha output. The `path` is the path prefix which is automatically
* prepended to each tested URI. The default is `/${attrs.id}`.
* Service Tester Constructor
*
* @param {object} attrs Refer to individual attrs
* @param {string} attrs.id
* Specifies which tests to run from the CLI or pull requests
* @param {string} attrs.title
* Prints in the Mocha output
* @param {string} attrs.path
* Prefix which is automatically prepended to each tested URI.
* The default is `/${attrs.id}`.
*/
constructor({ id, title, pathPrefix }) {
if (pathPrefix === undefined) {
@@ -31,6 +42,14 @@ class ServiceTester {
})
}
/**
* Construct a ServiceTester instance for a single service class
*
* @param {Function} ServiceClass
* A class that extends base-service/base.BaseService
* @returns {module:core/service-test-runner/service-tester~ServiceTester}
* ServiceTester for ServiceClass
*/
static forServiceClass(ServiceClass) {
const id = ServiceClass.name
const pathPrefix = ServiceClass.route.base
@@ -51,11 +70,13 @@ class ServiceTester {
/**
* Create a new test. The hard work is delegated to IcedFrisby.
* https://github.com/MarkHerhold/IcedFrisby/#show-me-some-code
* {@link https://github.com/MarkHerhold/IcedFrisby/#show-me-some-code}
*
* Note: The caller should not invoke toss() on the Frisby chain, as it's
* invoked automatically by the tester.
* @param msg The name of the test
*
* @param {string} msg The name of the test
* @returns {module:icedfrisby~IcedFrisby} IcedFrisby instance
*/
create(msg) {
const spec = frisby
@@ -90,8 +111,15 @@ class ServiceTester {
/**
* Register the tests with Mocha.
*
* @param {object} attrs Refer to individual attrs
* @param {string} attrs.baseUrl base URL for test server
* @param {boolean} attrs.skipIntercepted skip tests which intercept requests
* @param {object} attrs.retry retry configuration
* @param {number} attrs.retry.count number of times to retry test
* @param {number} attrs.retry.backoff number of milliseconds to add to the wait between each retry
*/
toss({ baseUrl, skipIntercepted }) {
toss({ baseUrl, skipIntercepted, retry }) {
const { specs, pathPrefix } = this
const testerBaseUrl = `${baseUrl}${pathPrefix}`
@@ -99,12 +127,17 @@ class ServiceTester {
// eslint-disable-next-line mocha/prefer-arrow-callback
fn(this.title, function() {
specs.forEach(spec => {
spec._message = `[${spec.hasIntercept ? 'mocked' : 'live'}] ${
spec._message
}`
if (!skipIntercepted || !spec.intercepted) {
spec.baseUri(testerBaseUrl)
spec.retry(retry.count, retry.backoff)
spec.toss()
}
})
})
}
}
module.exports = ServiceTester

View File

@@ -1,8 +1,20 @@
'use strict'
/**
* @module
*/
const difference = require('lodash.difference')
module.exports = function servicesForTitle(title) {
/**
* Given a pull request title like
* '[Travis Sonar] Support user token authentication'
* extract the list of service names in square brackets
* as an array of strings.
*
* @param {string} title Pull Request title
* @returns {string[]} Array of service names
*/
function servicesForTitle(title) {
const bracketed = /\[([^\]]+)\]/g
const preNormalized = title.toLowerCase()
@@ -18,3 +30,5 @@ module.exports = function servicesForTitle(title) {
const ignored = ['wip', 'rfc', 'security']
return difference(services, ignored)
}
module.exports = servicesForTitle

View File

@@ -1,8 +1,7 @@
'use strict'
const { promisify } = require('util')
const RedisServer = require('redis-server')
const redis = require('redis')
const Redis = require('ioredis')
const { expect } = require('chai')
const RedisTokenPersistence = require('./redis-token-persistence')
@@ -18,17 +17,15 @@ describe('Redis token persistence', function() {
const key = 'tokenPersistenceIntegrationTest'
let client
let redis
beforeEach(async function() {
client = redis.createClient()
const del = promisify(client.del).bind(client)
await del(key)
redis = new Redis()
await redis.del(key)
})
afterEach(async function() {
if (client) {
const quit = promisify(client.quit).bind(client)
await quit()
client = undefined
if (redis) {
await redis.quit()
redis = undefined
}
})
@@ -61,18 +58,12 @@ describe('Redis token persistence', function() {
const initialTokens = ['a', 'b', 'c'].map(char => char.repeat(40))
beforeEach(async function() {
const rpush = promisify(client.rpush).bind(client)
await rpush(key, initialTokens)
})
let lrange
beforeEach(function() {
lrange = promisify(client.lrange).bind(client)
await redis.sadd(key, initialTokens)
})
it('loads the contents', async function() {
const tokens = await persistence.initialize()
expect(tokens).to.deep.equal(initialTokens)
expect(tokens.sort()).to.deep.equal(initialTokens)
})
context('when tokens are added', function() {
@@ -84,8 +75,8 @@ describe('Redis token persistence', function() {
await persistence.initialize()
await persistence.noteTokenAdded(newToken)
const savedTokens = await lrange(key, 0, -1)
expect(savedTokens).to.deep.equal(expected)
const savedTokens = await redis.smembers(key)
expect(savedTokens.sort()).to.deep.equal(expected)
})
})
@@ -98,8 +89,8 @@ describe('Redis token persistence', function() {
await persistence.noteTokenRemoved(toRemove)
const savedTokens = await lrange(key, 0, -1)
expect(savedTokens).to.deep.equal(expected)
const savedTokens = await redis.smembers(key)
expect(savedTokens.sort()).to.deep.equal(expected)
})
})
})

View File

@@ -1,11 +1,11 @@
'use strict'
const { promisify } = require('util')
const redis = require('redis')
const { URL } = require('url')
const Redis = require('ioredis')
const log = require('../server/log')
const TokenPersistence = require('./token-persistence')
class RedisTokenPersistence extends TokenPersistence {
module.exports = class RedisTokenPersistence extends TokenPersistence {
constructor({ url, key }) {
super()
this.url = url
@@ -13,31 +13,31 @@ class RedisTokenPersistence extends TokenPersistence {
}
async initialize() {
this.client = redis.createClient(this.url)
this.client.on('error', e => {
const options =
this.url && this.url.startsWith('rediss:')
? {
// https://www.compose.com/articles/ssl-connections-arrive-for-redis-on-compose/
tls: { servername: new URL(this.url).hostname },
}
: undefined
this.redis = new Redis(this.url, options)
this.redis.on('error', e => {
log.error(e)
})
const lrange = promisify(this.client.lrange).bind(this.client)
const tokens = await lrange(this.key, 0, -1)
const tokens = await this.redis.smembers(this.key)
return tokens
}
async stop() {
const quit = promisify(this.client.quit).bind(this.client)
await quit()
await this.redis.quit()
}
async onTokenAdded(token) {
const rpush = promisify(this.client.rpush).bind(this.client)
await rpush(this.key, token)
await this.redis.sadd(this.key, token)
}
async onTokenRemoved(token) {
const lrem = promisify(this.client.lrem).bind(this.client)
await lrem(this.key, 0, token)
await this.redis.srem(this.key, token)
}
}
module.exports = RedisTokenPersistence

View File

@@ -1,9 +1,17 @@
'use strict'
/**
* @module
*/
const crypto = require('crypto')
const PriorityQueue = require('priorityqueuejs')
// Compute a one-way hash of the input string.
/**
* Compute a one-way hash of the input string.
*
* @param {string} id token
* @returns {string} hash
*/
function sanitizeToken(id) {
return crypto
.createHash('sha256')
@@ -15,11 +23,23 @@ function getUtcEpochSeconds() {
return (Date.now() / 1000) >>> 0
}
// Encapsulate a rate-limited token, with a user-provided ID and user-provided data.
//
// Each token has a notion of the number of uses remaining until exhausted,
// and the next reset time, when it can be used again even if it's exhausted.
/**
* Encapsulate a rate-limited token, with a user-provided ID and user-provided data.
*
* Each token has a notion of the number of uses remaining until exhausted,
* and the next reset time, when it can be used again even if it's exhausted.
*/
class Token {
/**
* Token Constructor
*
* @param {string} id token string
* @param {*} data reserved for future use
* @param {number} usesRemaining
* Number of uses remaining until the token is exhausted
* @param {number} nextReset
* Time when the token can be used again even if it's exhausted (unix timestamp)
*/
constructor(id, data, usesRemaining, nextReset) {
// Use underscores to avoid conflict with property accessors.
Object.assign(this, {
@@ -59,7 +79,14 @@ class Token {
return this.usesRemaining <= 0 && !this.hasReset
}
// Update the uses remaining and next reset time for a token.
/**
* Update the uses remaining and next reset time for a token.
*
* @param {number} usesRemaining
* Number of uses remaining until the token is exhausted
* @param {number} nextReset
* Time when the token can be used again even if it's exhausted (unix timestamp)
*/
update(usesRemaining, nextReset) {
if (!Number.isInteger(usesRemaining)) {
throw Error('usesRemaining must be an integer')
@@ -89,18 +116,24 @@ class Token {
}
}
// Indicate that the token should no longer be used.
/**
* Indicate that the token should no longer be used.
*/
invalidate() {
this._isValid = false
}
// Freeze the uses remaining and next reset values. Helpful for keeping
// stable ordering for a valid priority queue.
/**
* Freeze the uses remaining and next reset values. Helpful for keeping
* stable ordering for a valid priority queue.
*/
freeze() {
this._isFrozen = true
}
// Unfreeze the uses remaining and next reset values.
/**
* Unfreeze the uses remaining and next reset values.
*/
unfreeze() {
this._isFrozen = false
}
@@ -126,14 +159,21 @@ class Token {
// Large sentinel value which means "never reset".
Token.nextResetNever = Number.MAX_SAFE_INTEGER
// Encapsulate a collection of rate-limited tokens and choose the next
// available token when one is needed.
//
// Designed for the Github API, though may be also useful with other rate-
// limited APIs.
/**
* Encapsulate a collection of rate-limited tokens and choose the next
* available token when one is needed.
*
* Designed for the Github API, though may be also useful with other rate-
* limited APIs.
*/
class TokenPool {
// batchSize: The maximum number of times we use each token before moving
// on to the next one.
/**
* TokenPool Constructor
*
* @param {number} batchSize
* The maximum number of times we use each token before moving
* on to the next one.
*/
constructor({ batchSize = 1 } = {}) {
this.batchSize = batchSize
@@ -147,16 +187,29 @@ class TokenPool {
this.priorityQueue = new PriorityQueue(this.constructor.compareTokens)
}
// Use the token whose current rate allotment is expiring soonest.
/**
* compareTokens
*
* @param {module:core/token-pooling/token-pool~Token} first first token to compare
* @param {module:core/token-pooling/token-pool~Token} second second token to compare
* @returns {module:core/token-pooling/token-pool~Token} The token whose current rate allotment is expiring soonest.
*/
static compareTokens(first, second) {
return second.nextReset - first.nextReset
}
// Add a token with user-provided ID and data.
//
// The ID can be a primitive value or an object reference, and is used (with
// `Set`) for deduplication. If a token already exists with a given id, it
// will be ignored.
/**
* Add a token with user-provided ID and data.
*
* @param {string} id token string
* @param {*} data reserved for future use
* @param {number} usesRemaining
* Number of uses remaining until the token is exhausted
* @param {number} nextReset
* Time when the token can be used again even if it's exhausted (unix timestamp)
*
* @returns {boolean} Was the token added to the pool?
*/
add(id, data, usesRemaining, nextReset) {
if (this.tokenIds.has(id)) {
return false
@@ -210,31 +263,35 @@ class TokenPool {
throw Error('Token pool is exhausted')
}
// Obtain the next available token, returning `null` if no tokens are
// available.
//
// Tokens are initially pulled from a FIFO queue. The first token is used
// for a batch of requests, then returned to the queue to give those
// requests the opportunity to complete. The next token is used for the next
// batch of requests.
//
// This strategy allows a token to be used for concurrent requests, not just
// sequential request, and simplifies token recovery after errored and timed
// out requests.
//
// By the time the original token re-emerges, its requests should have long
// since completed. Even if a couple them are still running, they can
// reasonably be ignored. The uses remaining won't be 100% correct, but
// that's fine, because Shields uses only 75%
//
// The process continues until an exhausted token is pulled from the FIFO
// queue. At that time it's placed in the priority queue based on its
// scheduled reset time. To ensure the priority queue works as intended,
// the scheduled reset time is frozen then.
//
// After obtaining a token using `next()`, invoke `update()` on it to set a
// new use-remaining count and next-reset time. Invoke `invalidate()` to
// indicate it should not be reused.
/**
* Obtain the next available token, returning `null` if no tokens are
* available.
*
* Tokens are initially pulled from a FIFO queue. The first token is used
* for a batch of requests, then returned to the queue to give those
* requests the opportunity to complete. The next token is used for the next
* batch of requests.
*
* This strategy allows a token to be used for concurrent requests, not just
* sequential request, and simplifies token recovery after errored and timed
* out requests.
*
* By the time the original token re-emerges, its requests should have long
* since completed. Even if a couple them are still running, they can
* reasonably be ignored. The uses remaining won't be 100% correct, but
* that's fine, because Shields uses only 75%
*
* The process continues until an exhausted token is pulled from the FIFO
* queue. At that time it's placed in the priority queue based on its
* scheduled reset time. To ensure the priority queue works as intended,
* the scheduled reset time is frozen then.
*
* After obtaining a token using `next()`, invoke `update()` on it to set a
* new use-remaining count and next-reset time. Invoke `invalidate()` to
* indicate it should not be reused.
*
* @returns {module:core/token-pooling/token-pool~Token} token
*/
next() {
let token = this.currentBatch.token
const remaining = this.currentBatch.remaining
@@ -255,7 +312,11 @@ class TokenPool {
return token
}
// Iterate over all valid tokens.
/**
* Iterate over all valid tokens.
*
* @param {Function} callback function to execute on each valid token
*/
forEach(callback) {
function visit(item) {
if (item.isValid) {

View File

@@ -4,6 +4,15 @@ describe('Main page', function() {
const backendUrl = Cypress.env('backend_url')
const SEARCH_INPUT = 'input[placeholder="search / project URL"]'
function expectBadgeExample(title, previewUrl, pattern) {
cy.contains('tr', `${title}:`)
.find('code')
.should('have.text', pattern)
cy.contains('tr', `${title}:`)
.find('img')
.should('have.attr', 'src', previewUrl)
}
it('Search for badges', function() {
cy.visit('/')
@@ -12,20 +21,28 @@ describe('Main page', function() {
cy.contains('PyPI - License')
})
it('Shows badge from category', function() {
cy.visit('/category/chat')
expectBadgeExample(
'Discourse status',
'http://localhost:8080/badge/discourse-online-brightgreen',
'/discourse/status?server=https%3A%2F%2Fmeta.discourse.org'
)
})
it('Suggest badges', function() {
const badgeUrl = `${backendUrl}/github/issues/badges/shields.svg`
const badgeUrl = `${backendUrl}/github/issues/badges/shields`
cy.visit('/')
cy.get(SEARCH_INPUT).type('https://github.com/badges/shields')
cy.contains('Suggest badges').click()
cy.contains('GitHub issues')
cy.get(`img[src='${badgeUrl}']`)
cy.contains(badgeUrl)
expectBadgeExample('GitHub issues', badgeUrl, badgeUrl)
})
it('Customization form is filled with suggested badge details', function() {
const badgeUrl = `${backendUrl}/github/issues/badges/shields.svg`
const badgeUrl = `${backendUrl}/github/issues/badges/shields`
cy.visit('/')
cy.get(SEARCH_INPUT).type('https://github.com/badges/shields')
cy.contains('Suggest badges').click()
@@ -37,7 +54,7 @@ describe('Main page', function() {
})
it('Customizate suggested badge', function() {
const badgeUrl = `${backendUrl}/github/issues/badges/shields.svg`
const badgeUrl = `${backendUrl}/github/issues/badges/shields`
cy.visit('/')
cy.get(SEARCH_INPUT).type('https://github.com/badges/shields')
cy.contains('Suggest badges').click()
@@ -45,8 +62,6 @@ describe('Main page', function() {
cy.get('table input[name="color"]').type('orange')
cy.get(
`img[src='${backendUrl}/github/issues/badges/shields.svg?color=orange']`
)
cy.get(`img[src='${backendUrl}/github/issues/badges/shields?color=orange']`)
})
})

View File

@@ -106,19 +106,26 @@ if (allFiles.length > 100) {
warn("Lots 'o changes. Skipping diff-based checks.")
} else {
allFiles.forEach(file => {
if (file === 'dangerfile.js') {
return
}
// eslint-disable-next-line promise/prefer-await-to-then
danger.git.diffForFile(file).then(({ diff }) => {
if (/serverSecrets/.test(diff) && !secretsDocs.modified) {
if (
(diff.includes('authHelper') || diff.includes('serverSecrets')) &&
!secretsDocs.modified
) {
warn(
[
`:books: Remember to ensure any changes to \`serverSecrets\` `,
`:books: Remember to ensure any changes to \`config.private\` `,
`in \`${file}\` are reflected in the [server secrets documentation]`,
'(https://github.com/badges/shields/blob/master/doc/server-secrets.md)',
].join('')
)
}
if (/\+.*assert[(.]/.test(diff)) {
if (diff.includes('.assert(')) {
warn(
[
`Found 'assert' statement added in \`${file}\`. <br>`,
@@ -127,6 +134,15 @@ if (allFiles.length > 100) {
].join('')
)
}
if (diff.includes("require('joi')")) {
fail(
[
`Found import of 'joi' in \`${file}\`. <br>`,
"Joi must be imported as '@hapi/joi'.",
].join('')
)
}
})
})
}

View File

@@ -1,16 +1,17 @@
# Tutorial on how to add a badge for a service
This tutorial should help you add a service to shields.io in form of a badge.
You will need to learn to use JavaScript, Git and GitHub.
You will need to learn to use JavaScript, Git and GitHub, however, this document
will guide you through that journey if you are a beginner.
Please [improve the tutorial](https://github.com/badges/shields/edit/master/doc/TUTORIAL.md) while you read it.
## (1) Reading
You should read [CONTRIBUTING.md](../CONTRIBUTING.md)
You can also read previous
[merged pull-requests with the 'service-badge' label](https://github.com/badges/shields/pulls?utf8=%E2%9C%93&q=is%3Apr+label%3Aservice-badge+is%3Amerged)
to see how other people implemented their badges.
- [Contributing Guidance](../CONTRIBUTING.md)
- [Documentation](https://contributing.shields.io/index.html) for the Shields Core API
- You can also read previous
[merged pull-requests with the 'service-badge' label](https://github.com/badges/shields/pulls?utf8=%E2%9C%93&q=is%3Apr+label%3Aservice-badge+is%3Amerged)
to see how other people implemented their badges.
## (2) Setup
@@ -41,14 +42,9 @@ install node and npm: https://nodejs.org/en/download/
In case you get the _"getaddrinfo ENOTFOUND localhost"_ error, visit [http://127.0.0.1:3000/](http://127.0.0.1:3000) instead or take a look at [this issue](https://github.com/angular/angular-cli/issues/2227#issuecomment-358036526).
You may also want to install
[ImageMagick](https://www.imagemagick.org/script/download.php).
This is an optional dependency needed for generating badges in raster format,
but you can get a dev copy running without it.
## (3) Open an Issue
Before you want to implement your service, you may want to [open an issue](https://github.com/badges/shields/issues/new?template=2_Badge_request.md) and describe what you have in mind:
Before you want to implement your service, you may want to [open an issue](https://github.com/badges/shields/issues/new?template=3_Badge_request.md) and describe what you have in mind:
- What is the badge for?
- Which API do you want to use?
@@ -69,7 +65,7 @@ Each service has a directory for its files:
This might be the case when you add a badge for an API which is already used
by other badges.
Imagine a service that lives at https://img.shields.io/example/some-param-here.svg.
Imagine a service that lives at https://img.shields.io/example/some-param-here.
- For services with a single badge, the badge code will generally be stored in
`/services/example/example.service.js`.
@@ -94,14 +90,20 @@ Each service has a directory for its files:
All service badge classes inherit from [BaseService] or another class which extends it.
Other classes implement useful behavior on top of [BaseService].
- [BaseJsonService](https://github.com/badges/shields/blob/master/core/base-service/base-json.js)
- [BaseJsonService](https://contributing.shields.io/module-core_base-service_base-json-basejsonservice)
implements methods for performing requests to a JSON API and schema validation.
- [BaseXmlService](https://github.com/badges/shields/blob/master/core/base-service/base-xml.js)
- [BaseXmlService](https://contributing.shields.io/module-core_base-service_base-xml-basexmlservice)
implements methods for performing requests to an XML API and schema validation.
- [BaseYamlService](https://contributing.shields.io/module-core_base-service_base-yaml-baseyamlservice)
implements methods for performing requests to a YAML API and schema validation.
- [BaseSvgScrapingService](https://contributing.shields.io/module-core_base-service_base-svg-scraping-basesvgscrapingservice)
implements methods for retrieving information from existing third-party badges.
- [BaseGraphqlService](https://contributing.shields.io/module-core_base-service_base-graphql-basegraphqlservice)
implements methods for performing requests to a GraphQL API and schema validation.
- If you are contributing to a _service family_, you may define a common super
class for the badges or one may already exist.
[baseservice]: https://github.com/badges/shields/blob/master/core/base-service/base.js
[baseservice]: https://contributing.shields.io/module-core_base-service_base-baseservice
As a first step we will look at the code for an example which generates a badge without contacting an API.
@@ -144,17 +146,12 @@ Description of the code:
3. Our module must export a class which extends `BaseService`.
4. Returns the name of the category to sort this badge into (eg. "build"). Used to sort the examples on the main [shields.io](https://shields.io) website. [Here](https://github.com/badges/shields/blob/master/services/categories.js) is the list of the valid categories. See [section 4.4](#44-adding-an-example-to-the-front-page) for more details on examples.
5. `route()` declares the URL path at which the service operates. It also maps components of the URL path to handler parameters.
- `base` defines the first part of the URL that doesn't change, e.g. `/example/`.
- `pattern` defines the variable part of the route, everything that comes after `/example/`. It can include any
number of named parameters. These are converted into
regular expressions by [`path-to-regexp`][path-to-regexp]. the list of the valid categories can be seen
6. `route()` declares the URL path at which the service operates. It also maps components of the URL path to handler parameters.
- `base` defines the first part of the URL that doesn't change, e.g. `/example/`.
- `pattern` defines the variable part of the route, everything that comes after `/example/`. It can include any
number of named parameters. These are converted into
regular expressions by [`path-to-regexp`][path-to-regexp].
7. Because a service instance won't be created until it's time to handle a request, the route and other metadata must be obtained by examining the classes themselves. [That's why they're marked `static`.][static]
8. All badges must implement the `async handle()` function that receives parameters to render the badge. Parameters of `handle()` will match the name defined in `route()` Because we're capturing a single variable called `text` our function signature is `async handle({ text })`. `async` is needed to let JavaScript do other things while we are waiting for result from external API. Although in this simple case, we don't make any external calls. Our `handle()` function should return an object with 3 properties:
Because a service instance won't be created until it's time to handle a request, the route and other metadata must be obtained by examining the classes themselves. [That's why they're marked `static`.][static]
6. All badges must implement the `async handle()` function that receives parameters to render the badge. Parameters of `handle()` will match the name defined in `route()` Because we're capturing a single variable called `text` our function signature is `async handle({ text })`. `async` is needed to let JavaScript do other things while we are waiting for result from external API. Although in this simple case, we don't make any external calls. Our `handle()` function should return an object with 3 properties:
- `label`: the text on the left side of the badge
- `message`: the text on the right side of the badge - here we are passing through the parameter we captured in the route regex
- `color`: the background color of the right side of the badge
@@ -166,8 +163,8 @@ To try out this example badge:
1. Copy and paste this code into a new file in `/services/example/example.service.js`
2. The server should restart on its own. (If it doesn't for some reason, quit
the running server with `Control+C`, then start it again with `npm start`.)
3. Visit the badge at <http://localhost:8080/example/foo.svg>.
It should look like this: ![](https://img.shields.io/badge/example-foo-blue.svg)
3. Visit the badge at <http://localhost:8080/example/foo>.
It should look like this: ![](https://img.shields.io/badge/example-foo-blue)
[path-to-regexp]: https://github.com/pillarjs/path-to-regexp#parameters
[static]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static
@@ -188,7 +185,7 @@ const { renderVersionBadge } = require('..//version')
const { BaseJsonService } = require('..')
// (4)
const Joi = require('joi')
const Joi = require('@hapi/joi')
const schema = Joi.object({
version: Joi.string().required(),
}).required()
@@ -270,9 +267,9 @@ Description of the code:
11. The `static render()` method is responsible for formatting the data for display. `render()` is a pure function so we can make it a `static` method. By convention we declare functions which don't reference `this` as `static`. We could explicitly return an object here, as we did in the previous example. In this case, we will hand the version string off to `renderVersionBadge()` which will format it consistently and set an appropriate color. Because `renderVersionBadge()` doesn't return a `label` key, the default label we defined in `defaultBadgeData()` will be used when we generate the badge.
This code allows us to call this URL <https://img.shields.io/gem/v/formatador.svg> to generate this badge: ![](https://img.shields.io/gem/v/formatador.svg)
This code allows us to call this URL <https://img.shields.io/gem/v/formatador> to generate this badge: ![](https://img.shields.io/gem/v/formatador)
It is also worth considering the code we _haven't_ written here. Note that our example doesn't contain any explicit error handling code, but our badge handles errors gracefully. For example, if we call https://img.shields.io/gem/v/does-not-exist.svg we render a 'not found' badge ![](https://img.shields.io/gem/v/does-not-exist.svg) because https://rubygems.org/api/v1/gems/this-package-does-not-exist.json returns a `404 Not Found` status code. When dealing with well-behaved APIs, some of our error handling will be handled implicitly in `BaseJsonService`.
It is also worth considering the code we _haven't_ written here. Note that our example doesn't contain any explicit error handling code, but our badge handles errors gracefully. For example, if we call https://img.shields.io/gem/v/does-not-exist we render a 'not found' badge ![](https://img.shields.io/gem/v/does-not-exist) because https://rubygems.org/api/v1/gems/this-package-does-not-exist.json returns a `404 Not Found` status code. When dealing with well-behaved APIs, some of our error handling will be handled implicitly in `BaseJsonService`.
Specifically `BaseJsonService` will handle the following errors for us:
@@ -282,8 +279,8 @@ Specifically `BaseJsonService` will handle the following errors for us:
- API returns a response which doesn't validate against our schema
Sometimes it may be necessary to manually throw an exception to deal with a
non-standard error condition. If so, there are several standard exceptions that can be used. These exceptions are defined in
[errors.js](https://github.com/badges/shields/blob/master/services/errors.js)
non-standard error condition. If so, there are several standard exceptions that can be used. The errors are documented at
[errors](https://contributing.shields.io/module-core_base-service_errors.html)
and can be imported via the import shortcut and then thrown:
```js
@@ -327,7 +324,7 @@ module.exports = class GemVersion extends BaseJsonService {
- `namedParams`: Provide a valid example of params we can substitute into
the pattern. In this case we need a valid ruby gem, so we've picked [formatador](https://rubygems.org/gems/formatador).
- `staticPreview`: On the index page we want to show an example badge, but for performance reasons we want that example to be generated without making an API call. `staticPreview` should be populated by calling our `render()` method with some valid data.
- `keywords`: If we want to provide additional keywords other than the title, we can add them here. This helps users to search for relevant badges.
- `keywords`: If we want to provide additional keywords other than the title and the category, we can add them here. This helps users to search for relevant badges.
Save, run `npm start`, and you can see it [locally](http://127.0.0.1:3000/).

View File

@@ -22,7 +22,7 @@ module.exports = deprecatedService({
category: 'size',
route: {
base: 'imagelayers',
format: '(?:.+)',
format: '(?:.+?)',
},
label: 'imagelayers',
dateAdded: new Date('2019-xx-xx'), // Be sure to update this with today's date!

View File

@@ -7,22 +7,32 @@
[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 |
| -------------- | ------------------------ | ------------------------------------------------------------------------------------------ |
| Badge servers | Account owner | @espadrine |
| Badge servers | ssh, logs | @espadrine |
| Badge servers | Deployment | @espadrine, @paulmelnikow |
| Badge servers | Admin endpoints | @espadrine, @paulmelnikow |
| Cloudflare | Account owner | @espadrine |
| Cloudflare | Admin access | @espadrine, @paulmelnikow |
| GitHub | OAuth app | @espadrine ([could be transferred to the badges org][oauth transfer]) |
| DNS | Account owner | @olivierlacan |
| DNS | Read-only account access | @espadrine, @paulmelnikow, @chris48s |
| Sentry | Error reports | @espadrine, @paulmelnikow |
| Frontend | Deployment | Technically anyone with push access but in practice must be deployed with the badge server |
| Metrics server | Owner | @platan |
| UptimeRobot | Account owner | @paulmelnikow |
| More metrics | Owner | @RedSparr0w |
| Component | Subcomponent | People with access |
| ----------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------ |
| Badge servers | Account owner | @espadrine |
| Badge servers | ssh, logs | @espadrine |
| Badge servers | Deployment | @espadrine, @paulmelnikow |
| Badge servers | Admin endpoints | @espadrine, @paulmelnikow |
| Compose.io Redis | Account owner | @paulmelnikow |
| Compose.io Redis | Account access | @paulmelnikow |
| Compose.io Redis | Database connection credentials | @espadrine, @paulmelnikow |
| Zeit Now | Team owner | @paulmelnikow |
| Zeit Now | Team members | @paulmelnikow, @chris48s, @calebcartwright, @platan |
| 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 | Account owner | @espadrine |
| Cloudflare | Admin access | @espadrine, @paulmelnikow |
| GitHub | OAuth app | @espadrine ([could be transferred to the badges org][oauth transfer]) |
| Twitch | OAuth app | @PyvesB |
| OpenStreetMap (for Wheelmap) | Account owner | @paulmelnikow |
| DNS | Account owner | @olivierlacan |
| DNS | Read-only account access | @espadrine, @paulmelnikow, @chris48s |
| Sentry | Error reports | @espadrine, @paulmelnikow |
| Frontend | Deployment | Technically anyone with push access but in practice must be deployed with the badge server |
| Metrics server | Owner | @platan |
| UptimeRobot | Account owner | @paulmelnikow |
| More metrics | Owner | @RedSparr0w |
| Netlify (documentation site) | Owner | @chris48s |
There are [too many bottlenecks][issue 2577]!
@@ -32,9 +42,9 @@ There are three public badge servers on OVH VPSs.
| Cname | Hostname | Type | IP | Location |
| --------------------------- | -------------------- | ---- | -------------- | ------------------ |
| [s0.shields-server.com][s0] | vps71670.vps.ovh.ca | VPS | 192.99.59.72 | Quebec, Canada |
| [s1.shields-server.com][s1] | vps244529.ovh.net | VPS | 51.254.114.150 | Gravelines, France |
| [s2.shields-server.com][s2] | vps117870.vps.ovh.ca | VPS | 149.56.96.133 | Quebec, Canada |
| [s0.servers.shields.io][s0] | vps71670.vps.ovh.ca | VPS | 192.99.59.72 | Quebec, Canada |
| [s1.servers.shields.io][s1] | vps244529.ovh.net | VPS | 51.254.114.150 | Gravelines, France |
| [s2.servers.shields.io][s2] | vps117870.vps.ovh.ca | VPS | 149.56.96.133 | Quebec, Canada |
- These are single-core virtual hosts with 2 GB RAM [VPS SSD 1][].
- The Node version (v9.4.0 at time of writing) and dependency versions on the
@@ -52,9 +62,9 @@ There are three public badge servers on OVH VPSs.
- The public servers _do not_ use docker. The `Dockerfile` is included for
self-hosting (including on a Docker-capable PaaS).
[s0]: https://s0.shields-server.com/index.html
[s1]: https://s1.shields-server.com/index.html
[s2]: https://s2.shields-server.com/index.html
[s0]: https://s0.servers.shields.io/index.html
[s1]: https://s1.servers.shields.io/index.html
[s2]: https://s2.servers.shields.io/index.html
[vps ssd 1]: https://www.ovh.com/world/vps/vps-ssd.xml
[issue 1460]: https://github.com/badges/shields/issues/1460
[serverscript]: https://github.com/badges/ServerScript
@@ -63,18 +73,16 @@ There are three public badge servers on OVH VPSs.
Shields has mercifully little persistent state:
1. The GitHub tokens we collect are saved on each server in JSON files on disk.
They can be fetched from the [GitHub auth admin endpoint][] for debugging.
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.
2. The server keeps a few caches in memory. These are neither persisted nor
inspectable.
- The [request cache][]
- The [regular-update cache][]
- The [raster cache][]
[github auth admin endpoint]: https://github.com/badges/shields/blob/master/services/github/auth/admin.js
[request cache]: https://github.com/badges/shields/blob/master/core/base-service/legacy-request-handler.js#L29-L30
[regular-update cache]: https://github.com/badges/shields/blob/master/core/legacy/regular-update.js
[raster cache]: https://github.com/badges/shields/blob/master/gh-badges/lib/svg-to-img.js#L9-L10
[oauth transfer]: https://developer.github.com/apps/managing-oauth-apps/transferring-ownership-of-an-oauth-app/
## Configuration
@@ -98,7 +106,7 @@ files:
[start-shields.sh]: https://github.com/badges/ServerScript/blob/master/start-shields.sh#L7
[config]: https://github.com/lorenwest/node-config/wiki/Configuration-Files
[local-shields-io-production.yml]: ../config/local-shields-io-production.example.yml
[local-shields-io-production.yml]: ../config/local-shields-io-production.template.yml
[shields-io-production.yml]: ../config/shields-io-production.yml
[default.yml]: ../config/default.yml
@@ -128,6 +136,15 @@ with the badge server via the deployment process described below.
[github pages]: https://pages.github.com/
[gh-pages]: https://github.com/badges/shields/tree/gh-pages
## Raster server
The raster server `raster.shields.io` (a.k.a. the rasterizing proxy) is
hosted on [Zeit Now][]. It's managed in the
[svg-to-image-proxy repo][svg-to-image-proxy].
[zeit now]: https://zeit.co/now
[svg-to-image-proxy]: https://github.com/badges/svg-to-image-proxy
## Deployment
To set things up for deployment:
@@ -138,9 +155,9 @@ To set things up for deployment:
3. Add remotes:
```sh
git remote add s0 root@s0.shields-server.com:/home/m/shields.git
git remote add s1 root@s1.shields-server.com:/home/m/shields.git
git remote add s2 root@s2.shields-server.com:/home/m/shields.git
git remote add s0 root@s0.servers.shields.io:/home/m/shields.git
git remote add s1 root@s1.servers.shields.io:/home/m/shields.git
git remote add s2 root@s2.servers.shields.io:/home/m/shields.git
```
`origin` should point to GitHub as usual.

View File

@@ -152,7 +152,7 @@ Once the route is working, fill out `render()` and `handle()`.
<details>
```js
const Joi = require('joi')
const Joi = require('@hapi/joi')
const { errorMessagesFor } = require('./github-helpers')
const issueSchema = Joi.object({
@@ -181,7 +181,7 @@ or create an abstract superclass like **PypiBase**:
<details>
```js
const Joi = require('joi')
const Joi = require('@hapi/joi')
const BaseJsonService = require('../base-json')
const schema = Joi.object({

View File

@@ -69,7 +69,7 @@ Successfully built 4471b442c220
```
Optionally, create a file called `shields.env` that contains the needed
configuration. See [server-secrets.md](server-secrets.md) and [../config/custom-environment-variables.yml](config/custom-environment-variables.yml) for examples.
configuration. See [server-secrets.md](server-secrets.md) and [config/custom-environment-variables.yml](/config/custom-environment-variables.yml) for examples.
Then run the container:
@@ -93,6 +93,27 @@ machine.
[shields.example.env]: ../shields.example.env
## Raster server
If you want to host PNG badges, you can also self-host a [raster server][]
which points to your badge server. It's designed as a web function which is
tested on Zeit Now, though you may be able to run it on AWS Lambda. It's
built on the [micro][] framework, and comes with a `start` script that allows
it to run as a standalone Node service.
- In your raster instance, set `BASE_URL` to your Shields instance, e.g.
`https://shields.example.co`.
- Optionally, in your Shields, instance, configure `RASTER_URL` to the base
URL, e.g. `https://raster.example.co`. This will send 301 redirects
for the legacy raster URLs instead of 404's.
If anyone has set this up, more documentation on how to do this would be
welcome! It would also be nice to ship a Docker image that includes a
preconfigured raster server.
[raster server]: https://github.com/badges/svg-to-image-proxy
[micro]: https://github.com/zeit/micro
## Zeit Now
To deploy using Zeit Now:

View File

@@ -141,6 +141,14 @@ Create an account, sign in and obtain a uuid and token from your
to give your self-hosted Shields installation access to a
private SonarQube instance or private project on a public instance.
## Twitch
- `TWITCH_CLIENT_ID` (yml: `twitch_client_id`)
- `TWITCH_CLIENT_SECRET` (yml: `twitch_client_secret`)
Register an application in the [Twitch developer console](https://dev.twitch.tv/console)
in order to obtain a client id and a client secret for making Twitch API calls.
## Wheelmap
- `WHEELMAP_TOKEN` (yml: `wheelmap_token`)

View File

@@ -221,7 +221,7 @@ static render({ status, result }) {
We can also use nock to intercept API calls to return a known response body.
```js
t.create('Build passed (mocked)')
t.create('Build passed')
.get('/build/wercker/go-wercker-api.json')
.intercept(nock =>
nock('https://app.wercker.com/api/v3/applications/')
@@ -234,7 +234,7 @@ t.create('Build passed (mocked)')
color: 'brightgreen',
})
t.create('Build failed (mocked)')
t.create('Build failed')
.get('/build/wercker/go-wercker-api.json')
.intercept(nock =>
nock('https://app.wercker.com/api/v3/applications/')

View File

@@ -1,9 +1,8 @@
'use strict'
const { expect } = require('chai')
// https://github.com/nock/nock/issues/1523
const got = require('got').extend({ retry: 0 })
const isSvg = require('is-svg')
const got = require('./core/got-test-client')
let server
before(function() {

View File

@@ -1 +0,0 @@
extends: '../.eslintrc-frontend.yml'

View File

@@ -1,96 +0,0 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import {
badgeUrlFromPattern,
staticBadgeUrl,
} from '../../core/badge-urls/make-badge-url'
import { examplePropType } from '../lib/service-definitions/example-prop-types'
import { Badge } from './common'
import { StyledCode } from './snippet'
const ExampleTable = styled.table`
min-width: 50%;
margin: auto;
th,
td {
text-align: left;
}
`
const ClickableTh = styled.th`
cursor: pointer;
`
const ClickableCode = styled(StyledCode)`
cursor: pointer;
`
function Example({ baseUrl, onClick, exampleData }) {
const { title, example, preview } = exampleData
const { pattern, namedParams, queryParams } = example
const exampleUrl = badgeUrlFromPattern({
baseUrl,
pattern,
namedParams,
queryParams,
})
let previewUrl
if (preview.buildFromExample) {
previewUrl = exampleUrl
} else {
const { label, message, color, style, namedLogo } = preview
previewUrl = staticBadgeUrl({
baseUrl,
label,
message,
color,
style,
namedLogo,
})
}
const handleClick = () => onClick(exampleData)
return (
<tr>
<ClickableTh onClick={handleClick}>{title}:</ClickableTh>
<td>
<Badge clickable onClick={handleClick} src={previewUrl} />
</td>
<td>
<ClickableCode onClick={handleClick}>{exampleUrl}</ClickableCode>
</td>
</tr>
)
}
Example.propTypes = {
exampleData: examplePropType.isRequired,
baseUrl: PropTypes.string,
onClick: PropTypes.func.isRequired,
}
export default function BadgeExamples({ examples, baseUrl, onClick }) {
return (
<ExampleTable>
<tbody>
{examples.map(exampleData => (
<Example
baseUrl={baseUrl}
exampleData={exampleData}
key={`${exampleData.title} ${exampleData.example.pattern}`}
onClick={onClick}
/>
))}
</tbody>
</ExampleTable>
)
}
BadgeExamples.propTypes = {
examples: PropTypes.arrayOf(examplePropType).isRequired,
baseUrl: PropTypes.string,
onClick: PropTypes.func.isRequired,
}

View File

@@ -1,110 +0,0 @@
import React from 'react'
import { shallow } from 'enzyme'
import BadgeExamples from './badge-examples'
import '../enzyme-conf.spec'
const exampleServiceDefinitions = [
{
title: 'Mozilla Add-on',
example: {
pattern: '/amo/d/:addonId',
namedParams: {
addonId: 'dustman',
},
queryParams: {},
},
preview: {
label: 'downloads',
message: '12k',
color: 'brightgreen',
},
keywords: ['amo', 'firefox'],
},
{
title: 'Mozilla Add-on',
example: {
pattern: '/amo/rating/:addonId',
namedParams: {
addonId: 'dustman',
},
queryParams: {},
},
preview: {
label: 'rating',
message: '4/5',
color: 'brightgreen',
},
keywords: ['amo', 'firefox'],
},
{
title: 'Mozilla Add-on',
example: {
pattern: '/amo/stars/:addonId',
namedParams: {
addonId: 'dustman',
},
queryParams: {},
},
preview: {
label: 'stars',
message: '★★★★☆',
color: 'brightgreen',
},
keywords: ['amo', 'firefox'],
},
{
title: 'Mozilla Add-on',
example: {
pattern: '/amo/users/:addonId',
namedParams: {
addonId: 'dustman',
},
queryParams: {},
},
preview: {
label: 'users',
message: '750',
color: 'blue',
},
keywords: ['amo', 'firefox'],
},
{
title: 'Mozilla Add-on',
example: {
pattern: '/amo/v/:addonId',
namedParams: {
addonId: 'dustman',
},
queryParams: {},
},
preview: {
label: 'mozilla add-on',
message: 'v2.1.0',
color: 'blue',
},
keywords: ['amo', 'firefox'],
},
]
describe('<BadgeExamples />', function() {
it('renders with no examples', function() {
shallow(
<BadgeExamples
baseUrl="https://example.shields.io"
examples={[]}
onClick={() => {}}
/>
)
})
it('renders an array of examples', function() {
shallow(
<BadgeExamples
baseUrl="https://example.shields.io"
examples={exampleServiceDefinitions}
onClick={() => {}}
/>
)
})
})

View File

@@ -0,0 +1,125 @@
import React from 'react'
import styled from 'styled-components'
import {
badgeUrlFromPath,
badgeUrlFromPattern,
staticBadgeUrl,
} from '../../core/badge-urls/make-badge-url'
import { removeRegexpFromPattern } from '../lib/pattern-helpers'
import {
Example as ExampleData,
Suggestion,
RenderableExample,
} from '../lib/service-definitions'
import { Badge } from './common'
import { StyledCode } from './snippet'
const ExampleTable = styled.table`
min-width: 50%;
margin: auto;
th,
td {
text-align: left;
}
`
const ClickableTh = styled.th`
cursor: pointer;
`
const ClickableCode = styled(StyledCode)`
cursor: pointer;
`
function Example({
baseUrl,
onClick,
exampleData,
isBadgeSuggestion,
}: {
baseUrl?: string
onClick: (example: RenderableExample, isSuggestion: boolean) => void
exampleData: RenderableExample
isBadgeSuggestion: boolean
}) {
function handleClick() {
onClick(exampleData, isBadgeSuggestion)
}
let exampleUrl, previewUrl
if (isBadgeSuggestion) {
const {
example: { pattern, namedParams, queryParams },
} = exampleData as Suggestion
exampleUrl = previewUrl = badgeUrlFromPattern({
baseUrl,
pattern,
namedParams,
queryParams,
})
} else {
const {
example: { pattern, queryParams },
preview: { label, message, color, style, namedLogo },
} = exampleData as ExampleData
previewUrl = staticBadgeUrl({
baseUrl,
label: label || '',
message,
color,
style,
namedLogo,
})
exampleUrl = badgeUrlFromPath({
path: removeRegexpFromPattern(pattern),
queryParams,
})
}
const { title } = exampleData
return (
<tr>
<ClickableTh onClick={handleClick}>{title}:</ClickableTh>
<td>
<Badge
alt={`${title} badge`}
clickable
onClick={handleClick}
src={previewUrl}
/>
</td>
<td>
<ClickableCode onClick={handleClick}>{exampleUrl}</ClickableCode>
</td>
</tr>
)
}
export function BadgeExamples({
examples,
areBadgeSuggestions,
baseUrl,
onClick,
}: {
examples: RenderableExample[]
areBadgeSuggestions: boolean
baseUrl?: string
onClick: (exampleData: RenderableExample, isSuggestion: boolean) => void
}) {
return (
<ExampleTable>
<tbody>
{examples.map(exampleData => (
<Example
baseUrl={baseUrl}
exampleData={exampleData}
isBadgeSuggestion={areBadgeSuggestions}
key={`${exampleData.title} ${exampleData.example.pattern}`}
onClick={onClick}
/>
))}
</tbody>
</ExampleTable>
)
}

View File

@@ -1,33 +0,0 @@
import React from 'react'
import { shallow } from 'enzyme'
import { expect } from 'chai'
import { H3 } from './common'
import { CategoryHeading, CategoryHeadings } from './category-headings'
import '../enzyme-conf.spec'
const exampleCategories = [{ id: 'cat', name: 'Example category' }]
describe('<CategoryHeading />', function() {
it('renders', function() {
shallow(<CategoryHeading category={exampleCategories[0]} />)
})
it('contains the expected heading', function() {
const wrapper = shallow(<CategoryHeading category={exampleCategories[0]} />)
expect(wrapper).to.contain(<H3 id="cat">Example category</H3>)
})
})
describe('<CategoryHeadings />', function() {
it('renders', function() {
shallow(<CategoryHeadings categories={exampleCategories} />)
})
it('contains the expected child', function() {
const wrapper = shallow(<CategoryHeadings categories={exampleCategories} />)
expect(wrapper).to.contain(
<CategoryHeading category={exampleCategories[0]} />
)
})
})

View File

@@ -1,24 +1,26 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { Link } from 'gatsby'
import { H3 } from './common'
export function CategoryHeading({ category: { id, name } }) {
export interface Category {
id: string
name: string
}
export function CategoryHeading({
category: { id, name },
}: {
category: Category
}) {
return (
<Link to={`/category/${id}`}>
<H3 id={id}>{name}</H3>
</Link>
)
}
CategoryHeading.propTypes = {
category: PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}).isRequired,
}
export function CategoryHeadings({ categories }) {
export function CategoryHeadings({ categories }: { categories: Category[] }) {
return (
<div>
{categories.map(category => (
@@ -27,9 +29,6 @@ export function CategoryHeadings({ categories }) {
</div>
)
}
CategoryHeadings.propTypes = {
categories: PropTypes.arrayOf(CategoryHeading.propTypes.category).isRequired,
}
const StyledNav = styled.nav`
ul {
@@ -62,7 +61,7 @@ const StyledNav = styled.nav`
}
`
export function CategoryNav({ categories }) {
export function CategoryNav({ categories }: { categories: Category[] }) {
return (
<StyledNav>
<ul>
@@ -75,6 +74,3 @@ export function CategoryNav({ categories }) {
</StyledNav>
)
}
CategoryNav.propTypes = {
categories: PropTypes.arrayOf(CategoryHeading.propTypes.category).isRequired,
}

View File

@@ -1,69 +0,0 @@
import React from 'react'
import { shallow, render } from 'enzyme'
import { expect } from 'chai'
import * as common from './common'
import '../enzyme-conf.spec'
describe('Common modules', function() {
describe('<GlobalStyle />', function() {
it('renders', function() {
shallow(<common.GlobalStyle />)
})
})
describe('<BaseFont />', function() {
it('renders', function() {
shallow(<common.BaseFont />)
})
})
describe('<H2 />', function() {
it('renders', function() {
shallow(<common.H2 />)
})
})
describe('<H3 />', function() {
it('renders', function() {
shallow(<common.H3 />)
})
})
describe('<Badge />', function() {
it('renders', function() {
shallow(<common.Badge src="/badge/foo-bar-blue.svg" />)
})
it('contains a link to the image', function() {
const wrapper = render(<common.Badge src="/badge/foo-bar-blue.svg" />)
expect(wrapper.html()).to.contain(
'<img alt="" src="/badge/foo-bar-blue.svg">'
)
})
})
describe('<StyledInput />', function() {
it('renders', function() {
shallow(<common.StyledInput />)
})
})
describe('<InlineInput />', function() {
it('renders', function() {
shallow(<common.InlineInput />)
})
})
describe('<BlockInput />', function() {
it('renders', function() {
shallow(<common.BlockInput />)
})
})
describe('<VerticalSpace />', function() {
it('renders', function() {
shallow(<common.VerticalSpace />)
})
})
})

View File

@@ -1,12 +1,11 @@
import React from 'react'
import PropTypes from 'prop-types'
import styled, { css, createGlobalStyle } from 'styled-components'
export const noAutocorrect = Object.freeze({
autoComplete: 'off',
autoCorrect: 'off',
autoCapitalize: 'off',
spellCheck: 'false',
spellcheck: 'false',
})
export const nonBreakingSpace = '\u00a0'
@@ -41,7 +40,13 @@ export const H3 = styled.h3`
font-style: italic;
`
const BadgeWrapper = styled.span`
interface BadgeWrapperProps {
height: string
display: string
clickable: boolean
}
const BadgeWrapper = styled.span<BadgeWrapperProps>`
padding: 2px;
height: ${({ height }) => height};
vertical-align: middle;
@@ -54,6 +59,14 @@ const BadgeWrapper = styled.span`
`};
`
interface BadgeProps extends React.HTMLAttributes<HTMLImageElement> {
src: string
alt?: string
display?: 'inline' | 'block' | 'inline-block'
height?: string
clickable?: boolean
}
export function Badge({
src,
alt = '',
@@ -61,20 +74,13 @@ export function Badge({
height = '20px',
clickable = false,
...rest
}) {
}: BadgeProps) {
return (
<BadgeWrapper clickable={clickable} display={display} height={height}>
{src ? <img alt={alt} src={src} {...rest} /> : nonBreakingSpace}
</BadgeWrapper>
)
}
Badge.propTypes = {
src: PropTypes.string.isRequired,
alt: PropTypes.string,
display: PropTypes.oneOf(['inline', 'block', 'inline-block']),
height: PropTypes.string,
clickable: PropTypes.bool,
}
export const StyledInput = styled.input`
height: 15px;

Some files were not shown because too many files have changed in this diff Show More