Compare commits

..

5 Commits

Author SHA1 Message Date
chris48s
046856c056 fix 2022-02-08 19:36:56 +00:00
chris48s
851a30be39 test 2022-02-08 19:29:56 +00:00
chris48s
785ee090a9 test 2022-02-08 19:28:19 +00:00
chris48s
0002d6749e fix 2022-02-08 19:24:22 +00:00
chris48s
fb379c0556 lets not pretend this commit history is going to be meaningful 2022-02-08 19:22:47 +00:00
87 changed files with 2101 additions and 2852 deletions

View File

@@ -143,7 +143,7 @@ package_steps: &package_steps
jobs:
main:
docker:
- image: cimg/node:16.14
- image: circleci/node:16
environment:
NPM_CONFIG_ENGINE_STRICT: 'true'
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
@@ -152,13 +152,13 @@ jobs:
main@node-17:
docker:
- image: cimg/node:17.7
- image: circleci/node:17
<<: *main_steps
integration:
docker:
- image: cimg/node:16.14
- image: circleci/node:16
environment:
NPM_CONFIG_ENGINE_STRICT: 'true'
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
@@ -168,14 +168,14 @@ jobs:
integration@node-17:
docker:
- image: cimg/node:17.7
- image: circleci/node:17
- image: redis
<<: *integration_steps
danger:
docker:
- image: cimg/node:16.14
- image: circleci/node:16
steps:
- checkout
@@ -195,7 +195,7 @@ jobs:
frontend:
docker:
- image: cimg/node:16.14
- image: circleci/node:16
environment:
NPM_CONFIG_ENGINE_STRICT: 'true'
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
@@ -235,14 +235,13 @@ jobs:
command: npm run build
package:
machine:
image: 'ubuntu-2004:202111-02'
machine: true
<<: *package_steps
services:
docker:
- image: cimg/node:16.14
- image: circleci/node:16
environment:
NPM_CONFIG_ENGINE_STRICT: 'true'
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
@@ -251,7 +250,7 @@ jobs:
services@node-17:
docker:
- image: cimg/node:17.7
- image: circleci/node:17
<<: *services_steps

View File

@@ -10,7 +10,7 @@
"license": "CC0",
"dependencies": {
"@actions/core": "^1.6.0",
"@actions/github": "^5.0.1"
"@actions/github": "^5.0.0"
}
},
"node_modules/@actions/core": {
@@ -22,14 +22,14 @@
}
},
"node_modules/@actions/github": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.1.tgz",
"integrity": "sha512-JZGyPM9ektb8NVTTI/2gfJ9DL7Rk98tQ7OVyTlgTuaQroariRBsOnzjy0I2EarX4xUZpK88YyO503fhmjFdyAg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz",
"integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==",
"dependencies": {
"@actions/http-client": "^1.0.11",
"@octokit/core": "^3.6.0",
"@octokit/plugin-paginate-rest": "^2.17.0",
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
"@octokit/core": "^3.4.0",
"@octokit/plugin-paginate-rest": "^2.13.3",
"@octokit/plugin-rest-endpoint-methods": "^5.1.1"
}
},
"node_modules/@actions/http-client": {
@@ -41,21 +41,21 @@
}
},
"node_modules/@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz",
"integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==",
"dependencies": {
"@octokit/types": "^6.0.3"
}
},
"node_modules/@octokit/core": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.4.0.tgz",
"integrity": "sha512-6/vlKPP8NF17cgYXqucdshWqmMZGXkuvtcrWCgU5NOI0Pl2GjlmZyWgBMrU8zJ3v2MJlM6++CiB45VKYmhiWWg==",
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.3",
"@octokit/request": "^5.4.12",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
@@ -63,9 +63,9 @@
}
},
"node_modules/@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz",
"integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==",
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
@@ -73,37 +73,37 @@
}
},
"node_modules/@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.2.tgz",
"integrity": "sha512-WmsIR1OzOr/3IqfG9JIczI8gMJUMzzyx5j0XXQ4YihHtKlQc+u35VpVoOXhlKAlaBntvry1WpAzPl/a+s3n89Q==",
"dependencies": {
"@octokit/request": "^5.6.0",
"@octokit/request": "^5.3.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/openapi-types": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz",
"integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA=="
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.0.0.tgz",
"integrity": "sha512-gV/8DJhAL/04zjTI95a7FhQwS6jlEE0W/7xeYAzuArD0KVAVWDLP2f3vi98hs3HLTczxXdRK/mF0tRoQPpolEw=="
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz",
"integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==",
"version": "2.13.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.3.tgz",
"integrity": "sha512-46lptzM9lTeSmIBt/sVP/FLSTPGx6DCzAdSX3PfeJ3mTf4h9sGC26WpaQzMEq/Z44cOcmx8VsOhO+uEgE3cjYg==",
"dependencies": {
"@octokit/types": "^6.34.0"
"@octokit/types": "^6.11.0"
},
"peerDependencies": {
"@octokit/core": ">=2"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz",
"integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.1.1.tgz",
"integrity": "sha512-u4zy0rVA8darm/AYsIeWkRalhQR99qPL1D/EXHejV2yaECMdHfxXiTXtba8NMBSajOJe8+C9g+EqMKSvysx0dg==",
"dependencies": {
"@octokit/types": "^6.34.0",
"@octokit/types": "^6.14.1",
"deprecation": "^2.3.1"
},
"peerDependencies": {
@@ -111,22 +111,22 @@
}
},
"node_modules/@octokit/request": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
"version": "5.4.15",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.15.tgz",
"integrity": "sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag==",
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"@octokit/request-error": "^2.0.0",
"@octokit/types": "^6.7.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.7",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz",
"integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==",
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
@@ -134,17 +134,17 @@
}
},
"node_modules/@octokit/types": {
"version": "6.34.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz",
"integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==",
"version": "6.14.2",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.14.2.tgz",
"integrity": "sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA==",
"dependencies": {
"@octokit/openapi-types": "^11.2.0"
"@octokit/openapi-types": "^7.0.0"
}
},
"node_modules/before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz",
"integrity": "sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw=="
},
"node_modules/deprecation": {
"version": "2.3.1",
@@ -234,14 +234,14 @@
}
},
"@actions/github": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.1.tgz",
"integrity": "sha512-JZGyPM9ektb8NVTTI/2gfJ9DL7Rk98tQ7OVyTlgTuaQroariRBsOnzjy0I2EarX4xUZpK88YyO503fhmjFdyAg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz",
"integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==",
"requires": {
"@actions/http-client": "^1.0.11",
"@octokit/core": "^3.6.0",
"@octokit/plugin-paginate-rest": "^2.17.0",
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
"@octokit/core": "^3.4.0",
"@octokit/plugin-paginate-rest": "^2.13.3",
"@octokit/plugin-rest-endpoint-methods": "^5.1.1"
}
},
"@actions/http-client": {
@@ -253,21 +253,21 @@
}
},
"@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz",
"integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==",
"requires": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.4.0.tgz",
"integrity": "sha512-6/vlKPP8NF17cgYXqucdshWqmMZGXkuvtcrWCgU5NOI0Pl2GjlmZyWgBMrU8zJ3v2MJlM6++CiB45VKYmhiWWg==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.3",
"@octokit/request": "^5.4.12",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
@@ -275,9 +275,9 @@
}
},
"@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz",
"integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
@@ -285,54 +285,54 @@
}
},
"@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.2.tgz",
"integrity": "sha512-WmsIR1OzOr/3IqfG9JIczI8gMJUMzzyx5j0XXQ4YihHtKlQc+u35VpVoOXhlKAlaBntvry1WpAzPl/a+s3n89Q==",
"requires": {
"@octokit/request": "^5.6.0",
"@octokit/request": "^5.3.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz",
"integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA=="
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.0.0.tgz",
"integrity": "sha512-gV/8DJhAL/04zjTI95a7FhQwS6jlEE0W/7xeYAzuArD0KVAVWDLP2f3vi98hs3HLTczxXdRK/mF0tRoQPpolEw=="
},
"@octokit/plugin-paginate-rest": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz",
"integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==",
"version": "2.13.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.3.tgz",
"integrity": "sha512-46lptzM9lTeSmIBt/sVP/FLSTPGx6DCzAdSX3PfeJ3mTf4h9sGC26WpaQzMEq/Z44cOcmx8VsOhO+uEgE3cjYg==",
"requires": {
"@octokit/types": "^6.34.0"
"@octokit/types": "^6.11.0"
}
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz",
"integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.1.1.tgz",
"integrity": "sha512-u4zy0rVA8darm/AYsIeWkRalhQR99qPL1D/EXHejV2yaECMdHfxXiTXtba8NMBSajOJe8+C9g+EqMKSvysx0dg==",
"requires": {
"@octokit/types": "^6.34.0",
"@octokit/types": "^6.14.1",
"deprecation": "^2.3.1"
}
},
"@octokit/request": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
"version": "5.4.15",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.15.tgz",
"integrity": "sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"@octokit/request-error": "^2.0.0",
"@octokit/types": "^6.7.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.7",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz",
"integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
@@ -340,17 +340,17 @@
}
},
"@octokit/types": {
"version": "6.34.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz",
"integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==",
"version": "6.14.2",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.14.2.tgz",
"integrity": "sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA==",
"requires": {
"@octokit/openapi-types": "^11.2.0"
"@octokit/openapi-types": "^7.0.0"
}
},
"before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz",
"integrity": "sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw=="
},
"deprecation": {
"version": "2.3.1",

View File

@@ -11,6 +11,6 @@
"license": "CC0",
"dependencies": {
"@actions/core": "^1.6.0",
"@actions/github": "^5.0.1"
"@actions/github": "^5.0.0"
}
}

12
.github/actions/tester/action.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
name: 'Tester'
description: 'Just for debugging purposes'
branding:
icon: 'check-circle'
color: 'green'
inputs:
build-args:
description: 'List of build-time variables'
required: true
runs:
using: 'node12'
main: 'index.js'

10
.github/actions/tester/index.js vendored Normal file
View File

@@ -0,0 +1,10 @@
'use strict'
const core = require('@actions/core')
async function run() {
const buildArgs = await core.getInput('build-args', true)
console.log(buildArgs)
}
run()

416
.github/actions/tester/package-lock.json generated vendored Normal file
View File

@@ -0,0 +1,416 @@
{
"name": "close-bot",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "close-bot",
"version": "0.0.0",
"license": "CC0",
"dependencies": {
"@actions/core": "^1.6.0",
"@actions/github": "^5.0.0"
}
},
"node_modules/@actions/core": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz",
"integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==",
"dependencies": {
"@actions/http-client": "^1.0.11"
}
},
"node_modules/@actions/github": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz",
"integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==",
"dependencies": {
"@actions/http-client": "^1.0.11",
"@octokit/core": "^3.4.0",
"@octokit/plugin-paginate-rest": "^2.13.3",
"@octokit/plugin-rest-endpoint-methods": "^5.1.1"
}
},
"node_modules/@actions/http-client": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz",
"integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==",
"dependencies": {
"tunnel": "0.0.6"
}
},
"node_modules/@octokit/auth-token": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz",
"integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==",
"dependencies": {
"@octokit/types": "^6.0.3"
}
},
"node_modules/@octokit/core": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.4.0.tgz",
"integrity": "sha512-6/vlKPP8NF17cgYXqucdshWqmMZGXkuvtcrWCgU5NOI0Pl2GjlmZyWgBMrU8zJ3v2MJlM6++CiB45VKYmhiWWg==",
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.4.12",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/endpoint": {
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz",
"integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==",
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/graphql": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.2.tgz",
"integrity": "sha512-WmsIR1OzOr/3IqfG9JIczI8gMJUMzzyx5j0XXQ4YihHtKlQc+u35VpVoOXhlKAlaBntvry1WpAzPl/a+s3n89Q==",
"dependencies": {
"@octokit/request": "^5.3.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/openapi-types": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.0.0.tgz",
"integrity": "sha512-gV/8DJhAL/04zjTI95a7FhQwS6jlEE0W/7xeYAzuArD0KVAVWDLP2f3vi98hs3HLTczxXdRK/mF0tRoQPpolEw=="
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "2.13.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.3.tgz",
"integrity": "sha512-46lptzM9lTeSmIBt/sVP/FLSTPGx6DCzAdSX3PfeJ3mTf4h9sGC26WpaQzMEq/Z44cOcmx8VsOhO+uEgE3cjYg==",
"dependencies": {
"@octokit/types": "^6.11.0"
},
"peerDependencies": {
"@octokit/core": ">=2"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.1.1.tgz",
"integrity": "sha512-u4zy0rVA8darm/AYsIeWkRalhQR99qPL1D/EXHejV2yaECMdHfxXiTXtba8NMBSajOJe8+C9g+EqMKSvysx0dg==",
"dependencies": {
"@octokit/types": "^6.14.1",
"deprecation": "^2.3.1"
},
"peerDependencies": {
"@octokit/core": ">=3"
}
},
"node_modules/@octokit/request": {
"version": "5.4.15",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.15.tgz",
"integrity": "sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag==",
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.0.0",
"@octokit/types": "^6.7.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/request-error": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz",
"integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==",
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"node_modules/@octokit/types": {
"version": "6.14.2",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.14.2.tgz",
"integrity": "sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA==",
"dependencies": {
"@octokit/openapi-types": "^7.0.0"
}
},
"node_modules/before-after-hook": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz",
"integrity": "sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw=="
},
"node_modules/deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
},
"dependencies": {
"@actions/core": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz",
"integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==",
"requires": {
"@actions/http-client": "^1.0.11"
}
},
"@actions/github": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz",
"integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==",
"requires": {
"@actions/http-client": "^1.0.11",
"@octokit/core": "^3.4.0",
"@octokit/plugin-paginate-rest": "^2.13.3",
"@octokit/plugin-rest-endpoint-methods": "^5.1.1"
}
},
"@actions/http-client": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz",
"integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==",
"requires": {
"tunnel": "0.0.6"
}
},
"@octokit/auth-token": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz",
"integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==",
"requires": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.4.0.tgz",
"integrity": "sha512-6/vlKPP8NF17cgYXqucdshWqmMZGXkuvtcrWCgU5NOI0Pl2GjlmZyWgBMrU8zJ3v2MJlM6++CiB45VKYmhiWWg==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.4.12",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/endpoint": {
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz",
"integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/graphql": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.2.tgz",
"integrity": "sha512-WmsIR1OzOr/3IqfG9JIczI8gMJUMzzyx5j0XXQ4YihHtKlQc+u35VpVoOXhlKAlaBntvry1WpAzPl/a+s3n89Q==",
"requires": {
"@octokit/request": "^5.3.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.0.0.tgz",
"integrity": "sha512-gV/8DJhAL/04zjTI95a7FhQwS6jlEE0W/7xeYAzuArD0KVAVWDLP2f3vi98hs3HLTczxXdRK/mF0tRoQPpolEw=="
},
"@octokit/plugin-paginate-rest": {
"version": "2.13.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.3.tgz",
"integrity": "sha512-46lptzM9lTeSmIBt/sVP/FLSTPGx6DCzAdSX3PfeJ3mTf4h9sGC26WpaQzMEq/Z44cOcmx8VsOhO+uEgE3cjYg==",
"requires": {
"@octokit/types": "^6.11.0"
}
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.1.1.tgz",
"integrity": "sha512-u4zy0rVA8darm/AYsIeWkRalhQR99qPL1D/EXHejV2yaECMdHfxXiTXtba8NMBSajOJe8+C9g+EqMKSvysx0dg==",
"requires": {
"@octokit/types": "^6.14.1",
"deprecation": "^2.3.1"
}
},
"@octokit/request": {
"version": "5.4.15",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.15.tgz",
"integrity": "sha512-6UnZfZzLwNhdLRreOtTkT9n57ZwulCve8q3IT/Z477vThu6snfdkBuhxnChpOKNGxcQ71ow561Qoa6uqLdPtag==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.0.0",
"@octokit/types": "^6.7.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/request-error": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz",
"integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/types": {
"version": "6.14.2",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.14.2.tgz",
"integrity": "sha512-wiQtW9ZSy4OvgQ09iQOdyXYNN60GqjCL/UdMsepDr1Gr0QzpW6irIKbH3REuAHXAhxkEk9/F2a3Gcs1P6kW5jA==",
"requires": {
"@octokit/openapi-types": "^7.0.0"
}
},
"before-after-hook": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz",
"integrity": "sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw=="
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
}
}

16
.github/actions/tester/package.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
"name": "close-bot",
"version": "0.0.0",
"description": "",
"main": "index.js",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "chris48s",
"license": "CC0",
"dependencies": {
"@actions/core": "^1.6.0",
"@actions/github": "^5.0.0"
}
}

View File

@@ -12,9 +12,6 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Set Git Short SHA
run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: Build
uses: docker/build-push-action@v2
with:
@@ -22,4 +19,4 @@ jobs:
push: false
tags: shieldsio/shields:pr-validation
build-args: |
version=${{ env.SHORT_SHA }}
version=${GITHUB_SHA::7}

View File

@@ -20,9 +20,6 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set Git Short SHA
run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
- name: Build and push
uses: docker/build-push-action@v2
with:
@@ -30,4 +27,4 @@ jobs:
push: true
tags: shieldsio/shields:next
build-args: |
version=${{ env.SHORT_SHA }}
version=${GITHUB_SHA::7}

20
.github/workflows/test-build-args.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Tester
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install action dependencies
run: cd .github/actions/tester && npm ci
- name: Set Git Short SHA
run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
- uses: ./.github/actions/tester
with:
build-args: |
version=${{ env.SHORT_SHA }}

View File

@@ -4,47 +4,6 @@ Note: this changelog is for the shields.io server. The changelog for the badge-m
---
## server-2022-04-03
- fix installation issue on npm >= 8.5.5 [#7809](https://github.com/badges/shields/issues/7809)
- two fixes for [packagist] schemas [#7782](https://github.com/badges/shields/issues/7782)
- allow requireCloudflare setting to work when hosted on fly.io [#7781](https://github.com/badges/shields/issues/7781)
- fix [pypi] badges when package has null license [#7761](https://github.com/badges/shields/issues/7761)
- Add a [pub] publisher badge [#7715](https://github.com/badges/shields/issues/7715)
- Switch Steam file size badge to informational color [#7722](https://github.com/badges/shields/issues/7722)
- Make W3C and Youtube documentation links clickable [#7721](https://github.com/badges/shields/issues/7721)
- Improve Wercker examples [#7720](https://github.com/badges/shields/issues/7720)
- Improve Cirrus CI examples [#7719](https://github.com/badges/shields/issues/7719)
- Support [CodeClimate] responses with multiple data items [#7716](https://github.com/badges/shields/issues/7716)
- Delete [TeamCityCoverage] and [BowerVersion] redirectors [#7718](https://github.com/badges/shields/issues/7718)
- Deprecate [Shippable] service [#7717](https://github.com/badges/shields/issues/7717)
- fix: restore version comparison updates from #4173 [#4254](https://github.com/badges/shields/issues/4254)
- [piwheels], filter out versions with no files [#7696](https://github.com/badges/shields/issues/7696)
- set a longer cacheLength on [librariesio] badges [#7692](https://github.com/badges/shields/issues/7692)
- improve python version formatting [#7682](https://github.com/badges/shields/issues/7682)
- Clarify GitHub All Contributors badge [#7690](https://github.com/badges/shields/issues/7690)
- Support [HexPM] packages with no stable release [#7685](https://github.com/badges/shields/issues/7685)
- Add Test at Scale Badge [#7612](https://github.com/badges/shields/issues/7612)
- [packagist] api v2 support [#7681](https://github.com/badges/shields/issues/7681)
- Add [piwheels] version badge [#7656](https://github.com/badges/shields/issues/7656)
- Dependency updates
## server-2022-03-01
- Add [Conan] version service (#7460)
- remove suspended [github] tokens from the pool [#7654](https://github.com/badges/shields/issues/7654)
- generate links without trailing : if port not set [#7655](https://github.com/badges/shields/issues/7655)
- Use the latest build status when checking docs.rs [#7613](https://github.com/badges/shields/issues/7613)
- Remove no download handling and add API warning to [Wordpress] badges [#7606](https://github.com/badges/shields/issues/7606)
- set a higher default cacheLength on rating/star category [#7587](https://github.com/badges/shields/issues/7587)
- Update [amo] to use v4 API, set custom `cacheLength`s [#7586](https://github.com/badges/shields/issues/7586)
- fix(amo): include trailing slash in API call [#7585](https://github.com/badges/shields/issues/7585)
- fix docker image user agent [#7582](https://github.com/badges/shields/issues/7582)
- Delete deprecated Codetally and continuousphp services [#7572](https://github.com/badges/shields/issues/7572)
- Deprecate [Requires] service [#7571](https://github.com/badges/shields/issues/7571)
- [AUR] Fix RPC URL [#7570](https://github.com/badges/shields/issues/7570)
- Dependency updates
## server-2022-02-01
- [Depfu] Add support for Gitlab [#7475](https://github.com/badges/shields/issues/7475)

View File

@@ -35,7 +35,7 @@ and legible badges in SVG and raster format, which can easily be included in
GitHub readmes or any other web page. The service supports dozens of
continuous integration services, package registries, distributions, app
stores, social networks, code coverage services, and code analysis services.
Every month it serves over 870 million images and is used by some of the
Every month it serves over 770 million images and is used by some of the
world's most popular open-source projects, [VS Code][vscode], [Vue.js][vue]
and [Bootstrap][bootstrap] to name a few.

View File

@@ -10,7 +10,7 @@ Please follow this guidance when reporting security issues affecting:
- The [squint](https://github.com/badges/squint) raster proxy
- The [badge-maker](https://www.npmjs.com/package/badge-maker) NPM package
The [gh-badges](https://www.npmjs.com/package/gh-badges) and [svg-to-image-proxy](https://www.npmjs.com/package/svg-to-image-proxy) NPM packages are now deprecated and will no longer receive fixes for bugs or security issues.
The [gh-badges](https://www.npmjs.com/package/gh-badges) NPM package is now deprecated and will no longer receive fixes for bugs or security issues.
## Reporting a Vulnerability

View File

@@ -147,7 +147,6 @@ class BaseService {
version: 300,
debug: 60,
downloads: 900,
rating: 900,
social: 900,
}
return cacheLengths[this.category]

View File

@@ -201,14 +201,6 @@ function addHandlerAtIndex(camp, index, handlerFn) {
camp.stack.splice(index, 0, handlerFn)
}
function isOnHeroku() {
return !!process.env.DYNO
}
function isOnFly() {
return !!process.env.FLY_APP_NAME
}
/**
* The Server is based on the web framework Scoutcamp. It creates
* an http server, sets up helpers for token persistence and monitoring.
@@ -309,19 +301,13 @@ class Server {
// Set `req.ip`, which is expected by `cloudflareMiddleware()`. This is set
// by Express but not Scoutcamp.
addHandlerAtIndex(this.camp, 0, function (req, res, next) {
if (isOnHeroku()) {
// On Heroku, `req.socket.remoteAddress` is the Heroku router. However,
// the router ensures that the last item in the `X-Forwarded-For` header
// is the real origin.
// https://stackoverflow.com/a/18517550/893113
req.ip = req.headers['x-forwarded-for'].split(', ').pop()
} else if (isOnFly()) {
// On Fly we can use the Fly-Client-IP header
// https://fly.io/docs/reference/runtime-environment/#request-headers
req.ip = req.headers['fly-client-ip']
} else {
req.ip = req.socket.remoteAddress
}
// On Heroku, `req.socket.remoteAddress` is the Heroku router. However,
// the router ensures that the last item in the `X-Forwarded-For` header
// is the real origin.
// https://stackoverflow.com/a/18517550/893113
req.ip = process.env.DYNO
? req.headers['x-forwarded-for'].split(', ').pop()
: req.socket.remoteAddress
next()
})
addHandlerAtIndex(this.camp, 1, cloudflareMiddleware())

View File

@@ -25,9 +25,6 @@ export function getBaseUrl(): string {
if (['shields.io', 'www.shields.io'].includes(hostname)) {
return 'https://img.shields.io'
}
if (!port) {
return `${protocol}//${hostname}`
}
return `${protocol}//${hostname}:${port}`
} catch (e) {
// server-side rendering

2340
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -21,29 +21,28 @@
"url": "https://github.com/badges/shields"
},
"dependencies": {
"@fontsource/lato": "^4.5.5",
"@fontsource/lekton": "^4.5.6",
"@renovate/pep440": "^1.0.0",
"@sentry/node": "^6.19.3",
"@fontsource/lato": "^4.5.1",
"@fontsource/lekton": "^4.5.2",
"@sentry/node": "^6.17.4",
"@shields_io/camp": "^18.1.1",
"badge-maker": "file:badge-maker",
"bytes": "^3.1.2",
"camelcase": "^6.3.0",
"chalk": "^5.0.1",
"chalk": "^5.0.0",
"check-node-version": "^4.2.1",
"cloudflare-middleware": "^1.0.4",
"config": "^3.3.7",
"cross-env": "^7.0.3",
"decamelize": "^3.2.0",
"emojic": "^1.1.17",
"emojic": "^1.1.16",
"escape-string-regexp": "^4.0.0",
"fast-xml-parser": "^4.0.7",
"fast-xml-parser": "^4.0.2",
"glob": "^7.2.0",
"global-agent": "^3.0.0",
"got": "^12.0.3",
"got": "^12.0.1",
"graphql": "^15.6.1",
"graphql-tag": "^2.12.6",
"ioredis": "5.0.3",
"ioredis": "4.28.4",
"joi": "17.6.0",
"joi-extension-semver": "5.0.0",
"js-yaml": "^4.1.0",
@@ -55,13 +54,13 @@
"node-env-flag": "^0.1.0",
"parse-link-header": "^2.0.0",
"path-to-regexp": "^6.2.0",
"pretty-bytes": "^6.0.0",
"pretty-bytes": "^5.6.0",
"priorityqueuejs": "^2.0.0",
"prom-client": "^14.0.1",
"qs": "^6.10.3",
"query-string": "^7.1.1",
"semver": "~7.3.5",
"simple-icons": "6.17.0",
"simple-icons": "6.8.0",
"webextension-store-meta": "^1.0.5",
"xmldom": "~0.6.0",
"xpath": "~0.0.32"
@@ -141,9 +140,9 @@
]
},
"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/core": "^7.17.0",
"@babel/polyfill": "^7.12.1",
"@babel/register": "7.17.7",
"@babel/register": "7.17.0",
"@istanbuljs/schema": "^0.1.3",
"@mapbox/react-click-to-select": "^2.2.1",
"@types/chai": "^4.3.0",
@@ -154,13 +153,13 @@
"@types/react-helmet": "^6.1.5",
"@types/react-modal": "^3.13.1",
"@types/react-select": "^4.0.17",
"@types/styled-components": "5.1.24",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.15.0",
"@types/styled-components": "5.1.22",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.0",
"babel-plugin-inline-react-svg": "^2.0.1",
"babel-preset-gatsby": "^2.11.1",
"babel-preset-gatsby": "^2.5.1",
"c8": "^7.11.0",
"caller": "^1.1.0",
"caller": "^1.0.1",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
"chai-datetime": "^1.8.0",
@@ -168,46 +167,46 @@
"child-process-promise": "^2.2.1",
"clipboard-copy": "^4.0.1",
"concurrently": "^7.0.0",
"cypress": "^9.5.3",
"cypress": "^9.4.1",
"danger": "^11.0.2",
"danger-plugin-no-test-shortcuts": "^2.0.0",
"deepmerge": "^4.2.2",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-config-standard-jsx": "^10.0.0",
"eslint-config-standard-react": "^11.0.1",
"eslint-plugin-chai-friendly": "^0.7.2",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsdoc": "^38.1.6",
"eslint-plugin-jsdoc": "^37.7.1",
"eslint-plugin-mocha": "^10.0.3",
"eslint-plugin-no-extension-in-require": "^0.2.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.2.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-sort-class-members": "^1.14.1",
"fetch-ponyfill": "^7.1.0",
"form-data": "^4.0.0",
"gatsby": "4.6.2",
"gatsby-plugin-catch-links": "^4.11.0",
"gatsby-plugin-page-creator": "^4.7.0",
"gatsby-plugin-react-helmet": "^5.10.0",
"gatsby-plugin-remove-trailing-slashes": "^4.9.0",
"gatsby-plugin-styled-components": "^5.11.0",
"gatsby-plugin-typescript": "^4.11.1",
"gatsby-plugin-catch-links": "^4.5.0",
"gatsby-plugin-page-creator": "^4.3.0",
"gatsby-plugin-react-helmet": "^5.2.0",
"gatsby-plugin-remove-trailing-slashes": "^4.2.0",
"gatsby-plugin-styled-components": "^5.2.0",
"gatsby-plugin-typescript": "^4.2.0",
"humanize-string": "^2.1.0",
"icedfrisby": "4.0.0",
"icedfrisby-nock": "^2.1.0",
"is-svg": "^4.3.2",
"js-yaml-loader": "^1.2.2",
"jsdoc": "^3.6.10",
"lint-staged": "^12.3.7",
"lint-staged": "^12.3.3",
"lodash.debounce": "^4.0.8",
"lodash.difference": "^4.5.0",
"minimist": "^1.2.6",
"mocha": "^9.2.2",
"minimist": "^1.2.5",
"mocha": "^9.2.0",
"mocha-env-reporter": "^4.0.0",
"mocha-junit-reporter": "^2.0.2",
"mocha-yaml-loader": "^1.0.3",
@@ -217,7 +216,7 @@
"npm-run-all": "^4.1.5",
"open-cli": "^7.0.1",
"portfinder": "^1.0.28",
"prettier": "2.6.1",
"prettier": "2.5.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-error-overlay": "^6.0.10",
@@ -234,10 +233,10 @@
"sinon-chai": "^3.7.0",
"snap-shot-it": "^7.9.6",
"start-server-and-test": "1.14.0",
"styled-components": "^5.3.5",
"styled-components": "^5.3.3",
"ts-mocha": "^9.0.2",
"tsd": "^0.19.1",
"typescript": "^4.6.3",
"typescript": "^4.5.5",
"url": "^0.11.0"
},
"engines": {

View File

@@ -21,7 +21,7 @@ class BaseAmoService extends BaseJsonService {
async fetch({ addonId }) {
return this._requestJson({
schema,
url: `https://addons.mozilla.org/api/v4/addons/addon/${addonId}/`,
url: `https://addons.mozilla.org/api/v3/addons/addon/${addonId}`,
})
}
}

View File

@@ -24,8 +24,6 @@ class AmoWeeklyDownloads extends BaseAmoService {
},
]
static _cacheLength = 21600
static defaultBadgeData = { label: 'downloads' }
static render({ downloads }) {

View File

@@ -23,8 +23,6 @@ export default class AmoRating extends BaseAmoService {
},
]
static _cacheLength = 7200
static render({ format, rating }) {
rating = Math.round(rating)
return {

View File

@@ -14,8 +14,6 @@ export default class AmoUsers extends BaseAmoService {
},
]
static _cacheLength = 21600
static defaultBadgeData = { label: 'users' }
static render({ users: downloads }) {

View File

@@ -1,13 +1,13 @@
import Joi from 'joi'
import { renderVersionBadge } from '../version.js'
import { InvalidResponse } from '../index.js'
import { InvalidResponse, redirector } from '../index.js'
import BaseBowerService from './bower-base.js'
const queryParamSchema = Joi.object({
include_prereleases: Joi.equal(''),
}).required()
export default class BowerVersion extends BaseBowerService {
class BowerVersion extends BaseBowerService {
static category = 'version'
static route = { base: 'bower/v', pattern: ':packageName', queryParamSchema }
@@ -47,3 +47,18 @@ export default class BowerVersion extends BaseBowerService {
return renderVersionBadge({ version })
}
}
const BowerVersionRedirect = redirector({
category: 'version',
route: {
base: 'bower/vpre',
pattern: ':packageName',
},
transformPath: ({ packageName }) => `/bower/v/${packageName}`,
transformQueryParams: params => ({
include_prereleases: null,
}),
dateAdded: new Date('2019-12-15'),
})
export { BowerVersion, BowerVersionRedirect }

View File

@@ -4,7 +4,7 @@ import nock from 'nock'
import { cleanUpNockAfterEach, defaultContext } from '../test-helpers.js'
import { InvalidResponse } from '../index.js'
import LibrariesIoApiProvider from '../librariesio/librariesio-api-provider.js'
import BowerVersion from './bower-version.service.js'
import { BowerVersion } from './bower-version.service.js'
describe('BowerVersion', function () {
test(BowerVersion.transform, () => {

View File

@@ -33,3 +33,7 @@ t.create('Pre Version for Invalid Package')
.timeout(10000)
.get('/v/it-is-a-invalid-package-should-error.json?include_prereleases')
.expectBadge({ label: 'bower', message: 'package not found' })
t.create('Version (legacy redirect: vpre)')
.get('/vpre/bootstrap.svg')
.expectRedirect('/bower/v/bootstrap.svg?include_prereleases')

View File

@@ -26,29 +26,31 @@ export default class Cirrus extends BaseJsonService {
title: 'Cirrus CI - Base Branch Build Status',
namedParams: { user: 'flutter', repo: 'flutter' },
pattern: 'github/:user/:repo',
queryParams: { task: 'analyze', script: 'test' },
staticPreview: this.render({ status: 'passing' }),
},
{
title: 'Cirrus CI - Specific Branch Build Status',
pattern: 'github/:user/:repo/:branch',
namedParams: { user: 'flutter', repo: 'flutter', branch: 'master' },
queryParams: { task: 'analyze', script: 'test' },
staticPreview: this.render({ status: 'passing' }),
},
{
title: 'Cirrus CI - Specific Task Build Status',
pattern: 'github/:user/:repo',
queryParams: { task: 'build_docker' },
namedParams: { user: 'flutter', repo: 'cocoon' },
staticPreview: this.render({
subject: 'build_docker',
status: 'passing',
}),
queryParams: { task: 'analyze' },
namedParams: { user: 'flutter', repo: 'flutter' },
staticPreview: this.render({ subject: 'analyze', status: 'passing' }),
},
{
title: 'Cirrus CI - Task and Script Build Status',
pattern: 'github/:user/:repo',
queryParams: { task: 'build_docker', script: 'test' },
namedParams: { user: 'flutter', repo: 'cocoon' },
queryParams: { task: 'analyze', script: 'test' },
namedParams: {
user: 'flutter',
repo: 'flutter',
},
staticPreview: this.render({ subject: 'test', status: 'passing' }),
},
]

View File

@@ -138,19 +138,15 @@ export default class CodeclimateAnalysis extends BaseJsonService {
}
async fetch({ user, repo }) {
const repoInfos = await fetchRepo(this, { user, repo })
const repoInfosWithSnapshot = repoInfos.filter(
repoInfo => repoInfo.relationships.latest_default_branch_snapshot.data
)
if (repoInfosWithSnapshot.length === 0) {
throw new NotFound({ prettyMessage: 'snapshot not found' })
}
const {
id: repoId,
relationships: {
latest_default_branch_snapshot: { data: snapshotInfo },
},
} = repoInfosWithSnapshot[0]
} = await fetchRepo(this, { user, repo })
if (snapshotInfo === null) {
throw new NotFound({ prettyMessage: 'snapshot not found' })
}
const { data } = await this._requestJson({
schema,
url: `https://api.codeclimate.com/v1/repos/${repoId}/snapshots/${snapshotInfo.id}`,

View File

@@ -32,47 +32,6 @@ t.create('maintainability letter')
message: Joi.equal('A', 'B', 'C', 'D', 'E', 'F'),
})
t.create('issues when outer user repos query returns multiple items')
.get('/issues/angular/angular.json')
.intercept(nock =>
nock('https://api.codeclimate.com', { allowUnmocked: true })
.get('/v1/repos?github_slug=angular%2Fangular')
.reply(200, {
data: [
{
id: '54fd4e6b6956804a10003df4',
relationships: {
latest_default_branch_snapshot: {
data: null,
},
latest_default_branch_test_report: {
data: null,
},
},
},
{
id: '54fd4e6b6956804a10003df3',
relationships: {
latest_default_branch_snapshot: {
data: {
id: '620e2b491b6a72000100ca1d',
type: 'snapshots',
},
},
latest_default_branch_test_report: {
data: null,
},
},
},
],
})
)
.networkOn() // Combined with allowUnmocked: true, this allows the inner snapshots query to go through.
.expectBadge({
label: 'issues',
message: Joi.number().integer().positive(),
})
t.create('maintainability letter for non-existent repo')
.get('/maintainability/unknown/unknown.json')
.expectBadge({

View File

@@ -7,6 +7,7 @@ const isLetterGrade = Joi.equal('A', 'B', 'C', 'D', 'E', 'F').required()
const repoSchema = Joi.object({
data: Joi.array()
.max(1)
.items(
Joi.object({
id: Joi.string().required(),
@@ -28,15 +29,17 @@ const repoSchema = Joi.object({
}).required()
async function fetchRepo(serviceInstance, { user, repo }) {
const { data: repoInfos } = await serviceInstance._requestJson({
const {
data: [repoInfo],
} = await serviceInstance._requestJson({
schema: repoSchema,
url: 'https://api.codeclimate.com/v1/repos',
options: { searchParams: { github_slug: `${user}/${repo}` } },
})
if (repoInfos.length === 0) {
if (repoInfo === undefined) {
throw new NotFound({ prettyMessage: 'repo not found' })
}
return repoInfos
return repoInfo
}
export { keywords, isLetterGrade, fetchRepo }

View File

@@ -53,19 +53,15 @@ export default class CodeclimateCoverage extends BaseJsonService {
}
async fetch({ user, repo }) {
const repoInfos = await fetchRepo(this, { user, repo })
const repoInfosWithTestReport = repoInfos.filter(
repoInfo => repoInfo.relationships.latest_default_branch_test_report.data
)
if (repoInfosWithTestReport.length === 0) {
throw new NotFound({ prettyMessage: 'test report not found' })
}
const {
id: repoId,
relationships: {
latest_default_branch_test_report: { data: testReportInfo },
},
} = repoInfosWithTestReport[0]
} = await fetchRepo(this, { user, repo })
if (testReportInfo === null) {
throw new NotFound({ prettyMessage: 'test report not found' })
}
const { data } = await this._requestJson({
schema,
url: `https://api.codeclimate.com/v1/repos/${repoId}/test_reports/${testReportInfo.id}`,

View File

@@ -20,47 +20,6 @@ t.create('test coverage letter')
message: Joi.equal('A', 'B', 'C', 'D', 'E', 'F'),
})
t.create('test coverage when outer user repos query returns multiple items')
.get('/coverage/codeclimate/codeclimate.json')
.intercept(nock =>
nock('https://api.codeclimate.com', { allowUnmocked: true })
.get('/v1/repos?github_slug=codeclimate%2Fcodeclimate')
.reply(200, {
data: [
{
id: '558479d6e30ba034120008a8',
relationships: {
latest_default_branch_snapshot: {
data: null,
},
latest_default_branch_test_report: {
data: null,
},
},
},
{
id: '558479d6e30ba034120008a9',
relationships: {
latest_default_branch_snapshot: {
data: null,
},
latest_default_branch_test_report: {
data: {
id: '62110434a7160b00010b4b59',
type: 'test_reports',
},
},
},
},
],
})
)
.networkOn() // Combined with allowUnmocked: true, this allows the inner test reports query to go through.
.expectBadge({
label: 'coverage',
message: isIntegerPercentage,
})
t.create('test coverage percentage for non-existent repo')
.get('/coverage/unknown/unknown.json')
.expectBadge({

View File

@@ -3,7 +3,6 @@
* including colours based off download count, version number, etc.
*/
import moment from 'moment'
import pep440 from '@renovate/pep440'
function version(version) {
if (typeof version !== 'string' && typeof version !== 'number') {
@@ -21,17 +20,6 @@ function version(version) {
}
}
function pep440VersionColor(version) {
if (!pep440.valid(version)) {
return 'lightgrey'
}
const parsedVersion = pep440.explain(version)
if (parsedVersion.is_prerelease || parsedVersion.public.startsWith('0.')) {
return 'orange'
}
return 'blue'
}
function floorCount(value, yellow, yellowgreen, green) {
if (value <= 0) {
return 'red'
@@ -118,7 +106,6 @@ function age(date) {
export {
version,
pep440VersionColor,
downloadCount,
coveragePercentage,
floorCount,

View File

@@ -6,7 +6,6 @@ import {
letterScore,
age,
version,
pep440VersionColor,
} from './color-formatters.js'
describe('Color formatters', function () {
@@ -107,45 +106,4 @@ describe('Color formatters', function () {
"Can't generate a version color for [object Object]"
)
})
test(pep440VersionColor, () => {
forCases([
given('1.0.1'),
given('v2.1.6'),
given('1.0.1+abcd'),
given('1.0'),
given('v1'),
given(9),
given(1.0),
]).expect('blue')
forCases([
given('1.0.1-rc1'),
given('1.0.1rc1'),
given('1.0.0-Beta'),
given('1.0.0Beta'),
given('1.1.0-alpha'),
given('1.1.0alpha'),
given('1.0.1-dev'),
given('1.0.1dev'),
given('2.1.6-b1'),
given('2.1.6b1'),
given('0.1.0'),
given('v0.1.0'),
given('v2.1.6-b1'),
given('0.1.0+abcd'),
given('2.1.6-b1+abcd'),
given('0.0.0'),
given(0.1),
given('0.9'),
]).expect('orange')
forCases([
given('6.0.0-SNAPSHOT'),
given('2.1.6-prerelease'),
given(true),
given(null),
given('cheese'),
]).expect('lightgrey')
})
})

View File

@@ -1,21 +0,0 @@
import yaml from 'js-yaml'
import { NotFound, InvalidResponse } from '../index.js'
import { latest } from '../version.js'
export function parseLatestVersionFromConfig(configYaml) {
let versions
try {
const config = yaml.load(configYaml)
versions = Object.keys(config.versions)
} catch (err) {
throw new InvalidResponse({
prettyMessage: 'invalid config.yml',
underlyingError: err,
})
}
const version = latest(versions)
if (version == null) {
throw new NotFound({ prettyMessage: 'no versions found' })
}
return version
}

View File

@@ -1,33 +0,0 @@
import { expect } from 'chai'
import { NotFound, InvalidResponse } from '../index.js'
import { parseLatestVersionFromConfig } from './conan-version-helpers.js'
describe('parseLatestVersionFromConfig', function () {
it('returns latest available version', function () {
expect(
parseLatestVersionFromConfig(`
versions:
1.68.0:
folder: all
1.70.0:
folder: all
1.69.0:
folder: all
`)
).to.equal('1.70.0')
})
it('rejects invalid yaml', function () {
expect(() => parseLatestVersionFromConfig('[')).to.throw(InvalidResponse)
})
it('treats no results array as invalid', function () {
expect(() =>
parseLatestVersionFromConfig('somethingElse: whatever')
).to.throw(InvalidResponse)
})
it('treats empty results array as not found', function () {
expect(() => parseLatestVersionFromConfig('versions: []')).to.throw(
NotFound
)
})
})

View File

@@ -1,34 +0,0 @@
import { renderVersionBadge } from '../version.js'
import { ConditionalGithubAuthV3Service } from '../github/github-auth-service.js'
import { fetchRepoContent } from '../github/github-common-fetch.js'
import { parseLatestVersionFromConfig } from './conan-version-helpers.js'
export default class ConanVersion extends ConditionalGithubAuthV3Service {
static category = 'version'
static route = { base: 'conan/v', pattern: ':packageName' }
static examples = [
{
title: 'Conan Center',
namedParams: { packageName: 'boost' },
staticPreview: renderVersionBadge({ version: '1.78.0' }),
keywords: ['c++'],
},
]
static defaultBadgeData = { label: 'conan' }
async handle({ packageName }) {
const configContent = await fetchRepoContent(this, {
user: 'conan-io',
repo: 'conan-center-index',
branch: 'master',
filename: `recipes/${packageName}/config.yml`,
})
const version = parseLatestVersionFromConfig(configContent)
return renderVersionBadge({ version })
}
}

View File

@@ -1,17 +0,0 @@
import { isSemver } from '../test-validators.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('gets the package version of zeromq')
.get('/zeromq.json')
.expectBadge({ label: 'conan', message: isSemver })
t.create('returns not found for invalid package')
.get('/this package does not exist - shields test.json')
.expectBadge({
label: 'conan',
color: 'red',
message:
'repo not found, branch not found, or recipes/this package does not exist - shields test/config.yml missing',
})

View File

@@ -52,7 +52,9 @@ export default class DocsRs extends BaseJsonService {
}
async handle({ crate, version = 'latest' }) {
const [{ build_status: buildStatus }] = await this.fetch({ crate, version })
const { build_status: buildStatus } = (
await this.fetch({ crate, version })
).pop()
return this.constructor.render({ version, buildStatus })
}
}

View File

@@ -10,10 +10,6 @@ t.create('Failing docs')
.get('/tensorflow/0.16.1.json')
.expectBadge({ label: 'docs@0.16.1', message: 'failing' })
t.create('Multiple builds, latest passing')
.get('/bevy_tweening/0.3.1.json')
.expectBadge({ label: 'docs@0.3.1', message: 'passing' })
t.create('Getting latest version works')
.get('/rand/latest.json')
.expectBadge({

View File

@@ -2,17 +2,7 @@ import Joi from 'joi'
import { renderContributorBadge } from '../contributor-count.js'
import { ConditionalGithubAuthV3Service } from './github-auth-service.js'
import { fetchJsonFromRepo } from './github-common-fetch.js'
import { documentation as commonDocumentation } from './github-helpers.js'
const documentation = `
<p>
The All Contributors service allows you to recognize all your project
contributors, including those that don't push code. See
<a href="https://allcontributors.org">https://allcontributors.org</a>
for more information.
</p>
${commonDocumentation}
`
import { documentation } from './github-helpers.js'
const schema = Joi.object({
contributors: Joi.array().required(),
@@ -27,7 +17,7 @@ export default class GithubAllContributorsService extends ConditionalGithubAuthV
static examples = [
{
title: 'GitHub contributors (via allcontributors.org)',
title: 'Github All Contributors',
namedParams: {
repo: 'all-contributors',
user: 'all-contributors',

View File

@@ -77,7 +77,8 @@ class GithubApiProvider {
}
getV4RateLimitFromBody(body) {
const b = Joi.attempt(body, bodySchema)
const parsedBody = JSON.parse(body)
const b = Joi.attempt(parsedBody, bodySchema)
return {
rateLimit: b.data.rateLimit.limit,
totalUsesRemaining: b.data.rateLimit.remaining,
@@ -89,17 +90,8 @@ class GithubApiProvider {
let rateLimit, totalUsesRemaining, nextReset
if (url.startsWith('/graphql')) {
try {
const parsedBody = JSON.parse(res.body)
if ('message' in parsedBody && !('data' in parsedBody)) {
if (parsedBody.message === 'Sorry. Your account was suspended.') {
this.invalidateToken(token)
return
}
}
;({ rateLimit, totalUsesRemaining, nextReset } =
this.getV4RateLimitFromBody(parsedBody))
this.getV4RateLimitFromBody(res.body))
} catch (e) {
console.error(
`Could not extract rate limit info from response body ${res.body}`

View File

@@ -126,35 +126,14 @@ describe('Github API provider', function () {
})
})
context('unauthorized API responses', function () {
it('should invoke the callback and update the token with the expected values (unauthorized, v3)', async function () {
context('an unauthorized response', function () {
it('should invoke the callback and update the token with the expected values', async function () {
const mockResponse = { res: { statusCode: 401, headers: {} } }
const mockRequest = sinon.stub().resolves(mockResponse)
await provider.fetch(mockRequest, '/foo', {})
expect(mockStandardToken.invalidate).to.have.been.calledOnce
expect(mockStandardToken.update).not.to.have.been.called
})
it('should invoke the callback and update the token with the expected values (unauthorized, v4)', async function () {
const mockResponse = { res: { statusCode: 401, body: {} } }
const mockRequest = sinon.stub().resolves(mockResponse)
await provider.fetch(mockRequest, '/graphql', {})
expect(mockGraphqlToken.invalidate).to.have.been.calledOnce
expect(mockGraphqlToken.update).not.to.have.been.called
})
it('should invoke the callback and update the token with the expected values (suspended, v4)', async function () {
const mockResponse = {
res: {
statusCode: 200,
body: '{ "message": "Sorry. Your account was suspended." }',
},
}
const mockRequest = sinon.stub().resolves(mockResponse)
await provider.fetch(mockRequest, '/graphql', {})
expect(mockGraphqlToken.invalidate).to.have.been.calledOnce
expect(mockGraphqlToken.update).not.to.have.been.called
})
})
context('a connection error', function () {

View File

@@ -58,7 +58,7 @@ export default class GithubDeployments extends GithubAuthV4Service {
environment: 'shields-staging',
},
staticPreview: this.render({
state: 'SUCCESS',
state: 'success',
}),
documentation,
},

View File

@@ -1,4 +1,3 @@
import { pep440VersionColor } from '../color-formatters.js'
import { renderVersionBadge } from '../version.js'
import { isLockfile, getDependencyVersion } from '../pipenv-helpers.js'
import { addv } from '../text-formatters.js'
@@ -81,7 +80,6 @@ class GithubPipenvLockedPythonVersion extends ConditionalGithubAuthV3Service {
version,
tag: branch,
defaultLabel: 'python',
versionFormatter: pep440VersionColor,
})
}
@@ -149,7 +147,7 @@ class GithubPipenvLockedDependencyVersion extends ConditionalGithubAuthV3Service
return {
label: dependency,
message: version ? addv(version) : ref,
color: version ? pep440VersionColor(version) : 'blue',
color: 'blue',
}
}

View File

@@ -82,8 +82,10 @@ t.create('Locked version of unknown dependency')
})
t.create('Locked version of VCS dependency')
.get('/locked/dependency-version/GSS-Cogs/databaker-docker/databaker.json')
.get(
'/locked/dependency-version/DemocracyClub/aggregator-api/dc-base-theme.json'
)
.expectBadge({
label: 'databaker',
label: 'dc-base-theme',
message: isShortSha,
})

View File

@@ -1,7 +1,7 @@
import Joi from 'joi'
import { renderDownloadsBadge } from '../downloads.js'
import { maybePluralize } from '../text-formatters.js'
import { renderVersionBadge } from '../version.js'
import { addv, maybePluralize } from '../text-formatters.js'
import { version as versionColor } from '../color-formatters.js'
import { BaseJsonService } from '../index.js'
const hexSchema = Joi.object({
@@ -14,8 +14,7 @@ const hexSchema = Joi.object({
meta: Joi.object({
licenses: Joi.array().required(),
}).required(),
latest_stable_version: Joi.string(),
latest_version: Joi.string().required(),
latest_stable_version: Joi.string().required(),
}).required()
class BaseHexPmService extends BaseJsonService {
@@ -85,14 +84,12 @@ class HexPmVersion extends BaseHexPmService {
]
static render({ version }) {
return renderVersionBadge({ version })
return { message: addv(version), color: versionColor(version) }
}
async handle({ packageName }) {
const json = await this.fetch({ packageName })
return this.constructor.render({
version: json.latest_stable_version || json.latest_version,
})
return this.constructor.render({ version: json.latest_stable_version })
}
}

View File

@@ -1,10 +1,8 @@
import Joi from 'joi'
import { ServiceTester } from '../tester.js'
import {
isMetric,
isMetricOverTimePeriod,
isVPlusDottedVersionNClausesWithOptionalSuffix,
} from '../test-validators.js'
import { isMetric, isMetricOverTimePeriod } from '../test-validators.js'
const isHexpmVersion = Joi.string().regex(/^v\d+.\d+.?\d?$/)
export const t = new ServiceTester({ id: 'hexpm', title: 'Hex.pm' })
@@ -24,7 +22,6 @@ t.create('downloads (zero for period)')
.reply(200, {
downloads: { all: 100 }, // there is no 'day' key here
latest_stable_version: '1.0',
latest_version: '1.0',
meta: { licenses: ['MIT'] },
})
)
@@ -38,26 +35,9 @@ t.create('downloads (not found)')
.get('/dt/this-package-does-not-exist.json')
.expectBadge({ label: 'downloads', message: 'not found' })
t.create('version').get('/v/cowboy.json').expectBadge({
label: 'hex',
message: isVPlusDottedVersionNClausesWithOptionalSuffix,
})
t.create('version (no stable version)')
.get('/v/prima_opentelemetry_ex.json')
.intercept(nock =>
nock('https://hex.pm/')
.get('/api/packages/prima_opentelemetry_ex')
.reply(200, {
downloads: { all: 100 },
latest_version: '1.0.0-rc.3',
meta: { licenses: ['MIT'] },
})
)
.expectBadge({
label: 'hex',
message: isVPlusDottedVersionNClausesWithOptionalSuffix,
})
t.create('version')
.get('/v/cowboy.json')
.expectBadge({ label: 'hex', message: isHexpmVersion })
t.create('version (not found)')
.get('/v/this-package-does-not-exist.json')
@@ -77,7 +57,6 @@ t.create('license (multiple licenses)')
.reply(200, {
downloads: { all: 100 },
latest_stable_version: '1.0',
latest_version: '1.0',
meta: { licenses: ['GPLv2', 'MIT'] },
})
)
@@ -95,7 +74,6 @@ t.create('license (no license)')
.reply(200, {
downloads: { all: 100 },
latest_stable_version: '1.0',
latest_version: '1.0',
meta: { licenses: [] },
})
)

View File

@@ -81,8 +81,6 @@ class LibrariesIoProjectDependencies extends LibrariesIoBase {
},
]
static _cacheLength = 900
async handle({ platform, scope, packageName, version = 'latest' }) {
const url = `/${encodeURIComponent(platform)}/${
scope ? encodeURIComponent(`${scope}/`) : ''
@@ -118,8 +116,6 @@ class LibrariesIoRepoDependencies extends LibrariesIoBase {
},
]
static _cacheLength = 900
async handle({ user, repo }) {
const url = `/github/${encodeURIComponent(user)}/${encodeURIComponent(
repo

View File

@@ -32,8 +32,6 @@ export default class LibrariesIoDependentRepos extends LibrariesIoBase {
},
]
static _cacheLength = 900
static defaultBadgeData = {
label: 'dependent repos',
}

View File

@@ -32,8 +32,6 @@ export default class LibrariesIoDependents extends LibrariesIoBase {
},
]
static _cacheLength = 900
static defaultBadgeData = {
label: 'dependents',
}

View File

@@ -1,18 +1,18 @@
import Joi from 'joi'
import { BaseJsonService, NotFound } from '../index.js'
import { isStable, latest } from '../php-version.js'
import { BaseJsonService } from '../index.js'
const packageSchema = Joi.array().items(
Joi.object({
version: Joi.string().required(),
require: Joi.alternatives(
Joi.object({
const packageSchema = Joi.object()
.pattern(
/^/,
Joi.object({
'default-branch': Joi.bool(),
version: Joi.string(),
require: Joi.object({
php: Joi.string(),
}).required(),
Joi.string().valid('__unset')
),
})
)
}),
}).required()
)
.required()
const allVersionsSchema = Joi.object({
packages: Joi.object().pattern(/^/, packageSchema).required(),
@@ -36,31 +36,7 @@ class BasePackagistService extends BaseJsonService {
* @returns {object} Parsed response
*/
async fetch({ user, repo, schema, server = 'https://packagist.org' }) {
const url = `${server}/p2/${user.toLowerCase()}/${repo.toLowerCase()}.json`
return this._requestJson({
schema,
url,
})
}
/**
* Fetch dev releases method.
*
* This method utilize composer metadata API which
* "... is the preferred way to access the data as it is always up to date,
* and dumped to static files so it is very efficient on our end." (comment from official documentation).
* For more information please refer to https://packagist.org/apidoc#get-package-data.
*
* @param {object} attrs Refer to individual attrs
* @param {string} attrs.user package user
* @param {string} attrs.repo package repository
* @param {Joi} attrs.schema Joi schema to validate the response transformed to JSON
* @param {string} attrs.server URL for the packagist registry server (Optional)
* @returns {object} Parsed response
*/
async fetchDev({ user, repo, schema, server = 'https://packagist.org' }) {
const url = `${server}/p2/${user.toLowerCase()}/${repo.toLowerCase()}~dev.json`
const url = `${server}/p/${user.toLowerCase()}/${repo.toLowerCase()}.json`
return this._requestJson({
schema,
@@ -97,74 +73,16 @@ class BasePackagistService extends BaseJsonService {
})
}
getDefaultBranch(json, user, repo) {
const packageName = this.getPackageName(user, repo)
return Object.values(json.packages[packageName]).find(
b => b['default-branch'] === true
)
}
getPackageName(user, repo) {
return `${user.toLowerCase()}/${repo.toLowerCase()}`
}
/**
* Extract the array of minified versions of the given packageName,
* expand them back to their original format then return.
*
* @param {object} json The response of Packagist v2 API.
* @param {string} packageName The package name.
*
* @returns {object[]} An array of version metadata object.
*
* @see https://github.com/composer/metadata-minifier/blob/c549d23829536f0d0e984aaabbf02af91f443207/src/MetadataMinifier.php#L16-L46
*/
static expandPackageVersions(json, packageName) {
const versions = json.packages[packageName]
const expanded = []
let expandedVersion = null
for (const i in versions) {
const versionData = versions[i]
if (!expandedVersion) {
expandedVersion = { ...versionData }
expanded.push(expandedVersion)
continue
}
expandedVersion = { ...expandedVersion, ...versionData }
for (const key in expandedVersion) {
if (expandedVersion[key] === '__unset') {
delete expandedVersion[key]
}
}
expanded.push(expandedVersion)
}
return expanded
}
/**
* Find the object representation of the latest release.
*
* @param {object[]} versions An array of object representing a version.
* @param {boolean} includePrereleases Includes pre-release semver for the search.
*
* @returns {object} The object of the latest version.
* @throws {NotFound} Thrown if there is no item from the version array.
*/
findLatestRelease(versions, includePrereleases = false) {
// Find the latest version string, if not found, throw NotFound.
const versionStrings = versions
.filter(
version =>
typeof version.version === 'string' ||
version.version instanceof String
)
.map(version => version.version)
if (versionStrings.length < 1) {
throw new NotFound({ prettyMessage: 'no released version found' })
}
let release = latest(versionStrings)
if (!includePrereleases) {
release = latest(versionStrings.filter(isStable)) || release
}
return versions.filter(version => version.version === release)[0]
}
}
const customServerDocumentationFragment = `

View File

@@ -1,77 +0,0 @@
import { strict as assert } from 'assert'
import { describe, it } from 'mocha'
import { BasePackagistService } from './packagist-base.js'
// @reference: https://github.com/composer/metadata-minifier/blob/c549d23829536f0d0e984aaabbf02af91f443207/tests/MetadataMinifierTest.php#L36-L40
const minifiedSample = [
{
name: 'foo/bar',
version: '2.0.0',
version_normalized: '2.0.0.0',
type: 'library',
scripts: {
foo: 'bar',
},
license: ['MIT'],
},
{
version: '1.2.0',
version_normalized: '1.2.0.0',
license: ['GPL'],
homepage: 'https://example.org',
scripts: '__unset',
},
{
version: '1.0.0',
version_normalized: '1.0.0.0',
homepage: '__unset',
},
]
const expandedSample = [
{
name: 'foo/bar',
version: '2.0.0',
version_normalized: '2.0.0.0',
type: 'library',
scripts: {
foo: 'bar',
},
license: ['MIT'],
},
{
name: 'foo/bar',
version: '1.2.0',
version_normalized: '1.2.0.0',
type: 'library',
license: ['GPL'],
homepage: 'https://example.org',
},
{
name: 'foo/bar',
version: '1.0.0',
version_normalized: '1.0.0.0',
type: 'library',
license: ['GPL'],
},
]
describe('BasePackagistService', function () {
describe('expandPackageVersions', function () {
const expanded = BasePackagistService.expandPackageVersions(
{
packages: {
'foobar/foobar': minifiedSample,
},
},
'foobar/foobar'
)
it('should expand the minified package array to match the expanded sample', function () {
assert.deepStrictEqual(
expanded,
expandedSample,
'The expanded array should match the sample'
)
})
})
})

View File

@@ -8,11 +8,12 @@ import {
customServerDocumentationFragment,
} from './packagist-base.js'
const packageSchema = Joi.array()
.items(
const packageSchema = Joi.object()
.pattern(
/^/,
Joi.object({
version: Joi.string(),
license: Joi.array(),
'default-branch': Joi.bool(),
license: Joi.array().required(),
}).required()
)
.required()
@@ -56,27 +57,17 @@ export default class PackagistLicense extends BasePackagistService {
}
transform({ json, user, repo }) {
const packageName = this.getPackageName(user, repo)
const versions = BasePackagistService.expandPackageVersions(
json,
packageName
)
const version = this.findLatestRelease(versions)
const license = version.license
if (!license) {
throw new NotFound({ prettyMessage: 'license not found' })
const branch = this.getDefaultBranch(json, user, repo)
if (!branch) {
throw new NotFound({ prettyMessage: 'default branch not found' })
}
const { license } = branch
return { license }
}
async handle({ user, repo }, { server }) {
const json = await this.fetch({ user, repo, schema, server })
const { license } = this.transform({ json, user, repo })
return renderLicenseBadge({ license })
}
}

View File

@@ -3,101 +3,17 @@ import { NotFound } from '../index.js'
import PackagistLicense from './packagist-license.service.js'
describe('PackagistLicense', function () {
it('should return the license of the most recent release', function () {
it('should throw NotFound when default branch is missing', function () {
const json = {
packages: {
'frodo/the-one-package': [
{
version: '1.2.4',
license: 'MIT-latest',
},
{
version: '1.2.3',
license: 'MIT',
},
],
'frodo/the-one-package': {
'1.0.x-dev': { license: 'MIT' },
'1.1.x-dev': { license: 'MIT' },
'2.0.x-dev': { license: 'MIT' },
'2.1.x-dev': { license: 'MIT' },
},
},
}
expect(
PackagistLicense.prototype.transform({
json,
user: 'frodo',
repo: 'the-one-package',
})
)
.to.have.property('license')
.that.equals('MIT-latest')
})
it('should return the license of the most recent stable release', function () {
const json = {
packages: {
'frodo/the-one-package': [
{
version: '1.2.4-RC1', // Pre-release
license: 'MIT-latest',
},
{
version: '1.2.3', // Stable release
license: 'MIT',
},
],
},
}
expect(
PackagistLicense.prototype.transform({
json,
user: 'frodo',
repo: 'the-one-package',
})
)
.to.have.property('license')
.that.equals('MIT')
})
it('should return the license of the most recent pre-release if no stable releases', function () {
const json = {
packages: {
'frodo/the-one-package': [
{
version: '1.2.4-RC2',
license: 'MIT-latest',
},
{
version: '1.2.4-RC1',
license: 'MIT',
},
],
},
}
expect(
PackagistLicense.prototype.transform({
json,
user: 'frodo',
repo: 'the-one-package',
})
)
.to.have.property('license')
.that.equals('MIT-latest')
})
it('should throw NotFound when license key not in response', function () {
const json = {
packages: {
'frodo/the-one-package': [
{
version: '1.2.4',
},
{
version: '1.2.3',
},
],
},
}
expect(() =>
PackagistLicense.prototype.transform({
json,
@@ -106,6 +22,31 @@ describe('PackagistLicense', function () {
})
)
.to.throw(NotFound)
.with.property('prettyMessage', 'license not found')
.with.property('prettyMessage', 'default branch not found')
})
it('should return default branch when default branch is found', function () {
const json = {
packages: {
'frodo/the-one-package': {
'1.0.x-dev': { license: 'MIT' },
'1.1.x-dev': { license: 'MIT' },
'2.0.x-dev': {
license: 'MIT-default-branch',
'default-branch': true,
},
'2.1.x-dev': { license: 'MIT' },
},
},
}
expect(
PackagistLicense.prototype.transform({
json,
user: 'frodo',
repo: 'the-one-package',
})
)
.to.have.property('license')
.that.equals('MIT-default-branch')
})
})

View File

@@ -66,58 +66,11 @@ export default class PackagistPhpVersion extends BasePackagistService {
}
}
findVersionIndex(json, version) {
return json.findIndex(v => v.version === version)
}
async findSpecifiedVersion(json, user, repo, version, server) {
let release
if ((release = json[this.findVersionIndex(json, version)])) {
return release
} else {
try {
const allData = await this.fetchDev({
user,
repo,
schema: allVersionsSchema,
server,
})
const versions = BasePackagistService.expandPackageVersions(
allData,
this.getPackageName(user, repo)
)
return versions[this.findVersionIndex(versions, version)]
} catch (e) {
return release
}
}
}
async getPhpVersion({ json, user, repo, version = '', server }) {
let packageVersion
const versions = BasePackagistService.expandPackageVersions(
json,
this.getPackageName(user, repo)
)
if (version === '') {
packageVersion = this.findLatestRelease(versions)
} else {
try {
packageVersion = await this.findSpecifiedVersion(
versions,
user,
repo,
version,
server
)
} catch (e) {
packageVersion = null
}
}
transform({ json, user, repo, version = '' }) {
const packageVersion =
version === ''
? this.getDefaultBranch(json, user, repo)
: json.packages[this.getPackageName(user, repo)][version]
if (!packageVersion) {
throw new NotFound({ prettyMessage: 'invalid version' })
@@ -137,12 +90,11 @@ export default class PackagistPhpVersion extends BasePackagistService {
schema: allVersionsSchema,
server,
})
const { phpVersion } = await this.getPhpVersion({
const { phpVersion } = this.transform({
json: allData,
user,
repo,
version,
server,
})
return this.constructor.render({ php: phpVersion })
}

View File

@@ -1,115 +1,99 @@
import { expect } from 'chai'
import { NotFound } from '../index.js'
import PackagistPhpVersion from './packagist-php-version.service.js'
describe('PackagistPhpVersion', function () {
const json = {
packages: {
'frodo/the-one-package': [
{
version: '3.0.0',
require: { php: '^7.4 || 8' },
},
{
version: '2.0.0',
require: { php: '^7.2' },
},
{
version: '1.0.0',
require: { php: '^5.6 || ^7' },
},
],
'frodo/the-one-package': {
'1.0.0': { require: { php: '^5.6 || ^7' } },
'2.0.0': { require: { php: '^7.2' } },
'3.0.0': { require: { php: '^7.4 || 8' } },
'dev-main': { require: { php: '^8' }, 'default-branch': true },
},
'samwise/gardening': {
'1.0.x-dev': {},
'2.0.x-dev': {},
},
'pippin/mischief': {
'1.0.0': {},
'dev-main': { require: {}, 'default-branch': true },
},
},
}
it('should throw NotFound when package version is missing', async function () {
await expect(
PackagistPhpVersion.prototype.getPhpVersion({
it('should throw NotFound when package version is missing', function () {
expect(() =>
PackagistPhpVersion.prototype.transform({
json,
user: 'frodo',
repo: 'the-one-package',
version: '4.0.0',
})
).to.be.rejectedWith('invalid version')
)
.to.throw(NotFound)
.with.property('prettyMessage', 'invalid version')
})
it('should throw NotFound when PHP version not found on package when using default release', async function () {
const specJson = {
packages: {
'frodo/the-one-package': [
{
version: '3.0.0',
},
{
version: '2.0.0',
require: { php: '^7.2' },
},
{
version: '1.0.0',
require: { php: '^5.6 || ^7' },
},
],
},
}
await expect(
PackagistPhpVersion.prototype.getPhpVersion({
json: specJson,
user: 'frodo',
repo: 'the-one-package',
it('should throw NotFound when version not specified and no default branch found', function () {
expect(() =>
PackagistPhpVersion.prototype.transform({
json,
user: 'samwise',
repo: 'gardening',
})
).to.be.rejectedWith('version requirement not found')
)
.to.throw(NotFound)
.with.property('prettyMessage', 'invalid version')
})
it('should throw NotFound when PHP version not found on package when using specified release', async function () {
const specJson = {
packages: {
'frodo/the-one-package': [
{
version: '3.0.0',
require: { php: '^7.4 || 8' },
},
{
version: '2.0.0',
require: { php: '^7.2' },
},
{
version: '1.0.0',
require: '__unset',
},
],
},
}
await expect(
PackagistPhpVersion.prototype.getPhpVersion({
json: specJson,
user: 'frodo',
repo: 'the-one-package',
it('should throw NotFound when PHP version not found on package when using default branch', function () {
expect(() =>
PackagistPhpVersion.prototype.transform({
json,
user: 'pippin',
repo: 'mischief',
})
)
.to.throw(NotFound)
.with.property('prettyMessage', 'version requirement not found')
})
it('should throw NotFound when PHP version not found on package when using specified version', function () {
expect(() =>
PackagistPhpVersion.prototype.transform({
json,
user: 'pippin',
repo: 'mischief',
version: '1.0.0',
})
).to.be.rejectedWith('version requirement not found')
)
.to.throw(NotFound)
.with.property('prettyMessage', 'version requirement not found')
})
it('should return PHP version for the default release', async function () {
it('should return PHP version for the default branch', function () {
expect(
await PackagistPhpVersion.prototype.getPhpVersion({
PackagistPhpVersion.prototype.transform({
json,
user: 'frodo',
repo: 'the-one-package',
})
)
.to.have.property('phpVersion')
.that.equals('^8')
})
it('should return PHP version for the specified branch', function () {
expect(
PackagistPhpVersion.prototype.transform({
json,
user: 'frodo',
repo: 'the-one-package',
version: '3.0.0',
})
)
.to.have.property('phpVersion')
.that.equals('^7.4 || 8')
})
it('should return PHP version for the specified release', async function () {
expect(
await PackagistPhpVersion.prototype.getPhpVersion({
json,
user: 'frodo',
repo: 'the-one-package',
version: '2.0.0',
})
)
.to.have.property('phpVersion')
.that.equals('^7.2')
})
})

View File

@@ -6,8 +6,8 @@ t.create('gets the package version of symfony')
.get('/symfony/symfony.json')
.expectBadge({ label: 'php', message: isComposerVersion })
t.create('gets the package version of symfony 5.2.3')
.get('/symfony/symfony/v5.2.3.json')
t.create('gets the package version of symfony 2.8')
.get('/symfony/symfony/v2.8.0.json')
.expectBadge({ label: 'php', message: isComposerVersion })
t.create('package with no requirements')

View File

@@ -1,18 +1,26 @@
import Joi from 'joi'
import { renderVersionBadge } from '../version.js'
import { compare, isStable, latest } from '../php-version.js'
import { optionalUrl } from '../validators.js'
import { redirector } from '../index.js'
import { NotFound, redirector } from '../index.js'
import {
allVersionsSchema,
keywords,
BasePackagistService,
customServerDocumentationFragment,
} from './packagist-base.js'
const packageSchema = Joi.array().items(
Joi.object({
version: Joi.string().required(),
})
)
const packageSchema = Joi.object()
.pattern(
/^/,
Joi.object({
version: Joi.string(),
extra: Joi.object({
'branch-alias': Joi.object().pattern(/^/, Joi.string()),
}),
}).required()
)
.required()
const schema = Joi.object({
packages: Joi.object().pattern(/^/, packageSchema).required(),
@@ -72,9 +80,45 @@ class PackagistVersion extends BasePackagistService {
}
static render({ version }) {
if (version === undefined) {
throw new NotFound({ prettyMessage: 'no released version found' })
}
return renderVersionBadge({ version })
}
transform({ includePrereleases, json, user, repo }) {
const versionsData = json.packages[this.getPackageName(user, repo)]
let versions = Object.keys(versionsData)
const aliasesMap = {}
versions.forEach(version => {
const versionData = versionsData[version]
if (
versionData.extra &&
versionData.extra['branch-alias'] &&
versionData.extra['branch-alias'][version]
) {
// eg, version is 'dev-master', mapped to '2.0.x-dev'.
const validVersion = versionData.extra['branch-alias'][version]
if (
aliasesMap[validVersion] === undefined ||
compare(aliasesMap[validVersion], validVersion) < 0
) {
versions.push(validVersion)
aliasesMap[validVersion] = version
}
}
})
versions = versions.filter(version => !/^dev-/.test(version))
if (includePrereleases) {
return { version: latest(versions) }
} else {
const stableVersion = latest(versions.filter(isStable))
return { version: stableVersion || latest(versions) }
}
}
async handle(
{ user, repo },
{ include_prereleases: includePrereleases, server }
@@ -83,11 +127,10 @@ class PackagistVersion extends BasePackagistService {
const json = await this.fetch({
user,
repo,
schema,
schema: includePrereleases ? schema : allVersionsSchema,
server,
})
const versions = json.packages[this.getPackageName(user, repo)]
const { version } = this.findLatestRelease(versions, includePrereleases)
const { version } = this.transform({ includePrereleases, json, user, repo })
return this.constructor.render({ version })
}
}

View File

@@ -1,98 +0,0 @@
import Joi from 'joi'
import { BaseJsonService, InvalidResponse } from '../index.js'
import { renderVersionBadge } from '../version.js'
import { pep440VersionColor } from '../color-formatters.js'
const schema = Joi.object({
releases: Joi.object()
.pattern(
Joi.string(),
Joi.object({
prerelease: Joi.boolean().required(),
yanked: Joi.boolean().required(),
files: Joi.object().required(),
})
)
.required(),
}).required()
const queryParamSchema = Joi.object({
include_prereleases: Joi.equal(''),
}).required()
const keywords = ['python', 'arm', 'raspberry pi']
export default class PiWheelsVersion extends BaseJsonService {
static category = 'version'
static route = { base: 'piwheels/v', pattern: ':wheel', queryParamSchema }
static examples = [
{
title: 'piwheels',
namedParams: { wheel: 'numpy' },
staticPreview: this.render({ version: '1.22.2' }),
keywords,
},
{
title: 'piwheels (including prereleases)',
namedParams: { wheel: 'flask' },
queryParams: {
include_prereleases: null,
},
staticPreview: this.render({ version: '2.0.0rc2' }),
keywords,
},
]
static defaultBadgeData = { label: 'piwheels' }
static render({ version }) {
return renderVersionBadge({ version, versionFormatter: pep440VersionColor })
}
async fetch({ wheel }) {
return this._requestJson({
schema,
url: `https://www.piwheels.org/project/${wheel}/json/`,
errorMessages: { 404: 'package not found' },
})
}
static transform(releases, includePrereleases) {
const allReleases = Object.keys(releases)
.reduce(
(acc, key) =>
acc.concat({
version: key,
prerelease: releases[key].prerelease,
yanked: releases[key].yanked,
hasFiles: Object.keys(releases[key].files).length > 0,
}),
[]
)
.filter(release => !release.yanked) // exclude any yanked releases
.filter(release => release.hasFiles) // exclude any releases with no wheels
if (allReleases.length === 0) {
throw new InvalidResponse({ prettyMessage: 'no versions found' })
}
if (includePrereleases) {
return allReleases[0].version
}
const stableReleases = allReleases.filter(release => !release.prerelease)
if (stableReleases.length > 0) {
return stableReleases[0].version
}
return allReleases[0].version
}
async handle({ wheel }, queryParams) {
const includePrereleases = queryParams.include_prereleases !== undefined
const { releases } = await this.fetch({ wheel })
const version = this.constructor.transform(releases, includePrereleases)
return this.constructor.render({ version })
}
}

View File

@@ -1,65 +0,0 @@
import { expect } from 'chai'
import { test, given } from 'sazerac'
import { InvalidResponse } from '../index.js'
import PiWheelsVersion from './piwheels-version.service.js'
describe('PiWheelsVersion', function () {
test(PiWheelsVersion.transform, () => {
given(
{
'2.0.0rc1': { prerelease: true, yanked: false, files: { foobar: {} } },
'1.9.0': { prerelease: false, yanked: false, files: { foobar: {} } },
},
false
).expect('1.9.0')
given(
{
'2.0.0rc1': { prerelease: true, yanked: false, files: { foobar: {} } },
'1.9.0': { prerelease: false, yanked: false, files: { foobar: {} } },
},
true
).expect('2.0.0rc1')
given(
{
'2.0.0': { prerelease: false, yanked: true, files: { foobar: {} } },
'1.9.0': { prerelease: false, yanked: false, files: { foobar: {} } },
},
false
).expect('1.9.0')
given(
{
'2.0.0': { prerelease: false, yanked: false, files: {} },
'1.9.0': { prerelease: false, yanked: false, files: { foobar: {} } },
},
false
).expect('1.9.0')
given(
{
'2.0.0': { prerelease: false, yanked: false, files: { foobar: {} } },
'1.9.0': { prerelease: false, yanked: false, files: { foobar: {} } },
},
false
).expect('2.0.0')
given(
{
'2.0.0rc2': { prerelease: true, yanked: false, files: { foobar: {} } },
'2.0.0rc1': { prerelease: true, yanked: false, files: { foobar: {} } },
},
false
).expect('2.0.0rc2')
})
it('throws `no releases` InvalidResponse if no versions', function () {
expect(() =>
PiWheelsVersion.transform(
{
'1.0.1': { prerelease: false, yanked: false, files: {} },
'1.0.0': { prerelease: false, yanked: true, files: { foobar: {} } },
},
false
)
)
.to.throw(InvalidResponse)
.with.property('prettyMessage', 'no versions found')
})
})

View File

@@ -1,13 +0,0 @@
import { isVPlusDottedVersionNClauses } from '../test-validators.js'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('version (valid)').get('/flask.json').expectBadge({
label: 'piwheels',
message: isVPlusDottedVersionNClauses,
})
t.create('version (does not exist)').get('/doesn-not-exist.json').expectBadge({
label: 'piwheels',
message: 'package not found',
})

View File

@@ -1,49 +0,0 @@
import Joi from 'joi'
import { BaseJsonService } from '../index.js'
const schema = Joi.object({
publisherId: Joi.string().allow(null).required(),
}).required()
export class PubPublisher extends BaseJsonService {
static category = 'other'
static route = {
base: 'pub/publisher',
pattern: ':packageName',
}
static examples = [
{
title: 'Pub Publisher',
namedParams: { packageName: 'path' },
staticPreview: this.render({ publisher: 'dart.dev' }),
keywords: ['dart', 'dartlang'],
},
]
static _cacheLength = 3600
static defaultBadgeData = { label: 'publisher' }
static render({ publisher }) {
return {
label: 'publisher',
message: publisher == null ? 'unverified' : publisher,
color: publisher == null ? 'lightgrey' : 'blue',
}
}
async fetch({ packageName }) {
return this._requestJson({
schema,
url: `https://pub.dev/api/packages/${packageName}/publisher`,
})
}
async handle({ packageName }) {
const data = await this.fetch({ packageName })
const publisher = data.publisherId
return this.constructor.render({ publisher })
}
}

View File

@@ -1,18 +0,0 @@
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('package publisher').get('/path.json').expectBadge({
label: 'publisher',
message: 'dart.dev',
})
t.create('package not verified publisher').get('/utf.json').expectBadge({
label: 'publisher',
message: 'unverified',
color: 'lightgrey',
})
t.create('package not found').get('/does-not-exist.json').expectBadge({
label: 'publisher',
message: 'not found',
})

View File

@@ -5,8 +5,7 @@ const schema = Joi.object({
info: Joi.object({
version: Joi.string().required(),
// https://github.com/badges/shields/issues/2022
// https://github.com/badges/shields/issues/7728
license: Joi.string().allow('').allow(null),
license: Joi.string().allow(''),
classifiers: Joi.array().items(Joi.string()).required(),
}).required(),
releases: Joi.object()

View File

@@ -104,12 +104,6 @@ describe('PyPI helpers', function () {
'MIT',
])
forCases([
given({
info: {
license: null,
classifiers: ['License :: OSI Approved :: MIT License'],
},
}),
given({
info: {
license: '',

View File

@@ -1,4 +1,3 @@
import { pep440VersionColor } from '../color-formatters.js'
import { renderVersionBadge } from '../version.js'
import PypiBase from './pypi-base.js'
@@ -20,7 +19,7 @@ export default class PypiVersion extends PypiBase {
static defaultBadgeData = { label: 'pypi' }
static render({ version }) {
return renderVersionBadge({ version, versionFormatter: pep440VersionColor })
return renderVersionBadge({ version })
}
async handle({ egg }) {

View File

@@ -2,11 +2,9 @@ import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()
t.create('grade of https://shields.io')
.timeout(15000)
.get('/security-headers.json?url=https://shields.io')
.expectBadge({ label: 'security headers', message: 'F', color: 'red' })
t.create('grade of https://httpstat.us/301 as redirect')
.timeout(15000)
.get('/security-headers.json?ignoreRedirects&url=https://httpstat.us/301')
.expectBadge({ label: 'security headers', message: 'R', color: 'blue' })

View File

@@ -1,11 +1,80 @@
import { deprecatedService } from '../index.js'
import Joi from 'joi'
import { renderBuildStatusBadge } from '../build-status.js'
import { BaseJsonService, NotFound, redirector } from '../index.js'
export default deprecatedService({
// source: https://github.com/badges/shields/pull/1362#discussion_r161693830
const statusCodes = {
0: 'waiting',
10: 'queued',
20: 'processing',
30: 'success',
40: 'skipped',
50: 'unstable',
60: 'timeout',
70: 'cancelled',
80: 'failed',
90: 'stopped',
}
const schema = Joi.array()
.items(
Joi.object({
branchName: Joi.string().required(),
statusCode: Joi.number()
.valid(...Object.keys(statusCodes).map(key => parseInt(key)))
.required(),
}).required()
)
.required()
class Shippable extends BaseJsonService {
static category = 'build'
static route = {
base: 'shippable',
pattern: ':projectId/:branch+',
}
static examples = [
{
title: 'Shippable',
namedParams: {
projectId: '5444c5ecb904a4b21567b0ff',
branch: 'master',
},
staticPreview: this.render({ code: 30 }),
},
]
static defaultBadgeData = { label: 'shippable' }
static render({ code }) {
return renderBuildStatusBadge({ label: 'build', status: statusCodes[code] })
}
async fetch({ projectId }) {
const url = `https://api.shippable.com/projects/${projectId}/branchRunStatus`
return this._requestJson({ schema, url })
}
async handle({ projectId, branch }) {
const data = await this.fetch({ projectId })
const builds = data.filter(result => result.branchName === branch)
if (builds.length === 0) {
throw new NotFound({ prettyMessage: 'branch not found' })
}
return this.constructor.render({ code: builds[0].statusCode })
}
}
const ShippableRedirect = redirector({
category: 'build',
route: {
base: 'shippable',
format: '(?:.+?)',
pattern: ':projectId',
},
label: 'shippable',
dateAdded: new Date('2022-03-12'),
transformPath: ({ projectId }) => `/shippable/${projectId}/master`,
dateAdded: new Date('2020-07-18'),
})
export { Shippable, ShippableRedirect }

View File

@@ -1,20 +1,35 @@
import { isBuildStatus } from '../build-status.js'
import { ServiceTester } from '../tester.js'
export const t = new ServiceTester({
id: 'shippable',
id: 'Shippable',
title: 'Shippable',
pathPrefix: '/shippable',
})
t.create('no longer available (previously build status with branch)')
t.create('build status (valid)')
.get('/5444c5ecb904a4b21567b0ff/master.json')
.expectBadge({
label: 'shippable',
message: 'no longer available',
label: 'build',
message: isBuildStatus,
})
t.create('no longer available (previously build status without branch)')
.get('/5444c5ecb904a4b21567b0ff.json')
.expectBadge({
label: 'shippable',
message: 'no longer available',
})
t.create('build status (branch not found)')
.get('/5444c5ecb904a4b21567b0ff/not-a-branch.json')
.expectBadge({ label: 'shippable', message: 'branch not found' })
t.create('build status (build not found)')
.get('/not-a-build/master.json')
.expectBadge({ label: 'shippable', message: 'not found' })
t.create('build status (unexpected status code)')
.get('/5444c5ecb904a4b21567b0ff/master.json')
.intercept(nock =>
nock('https://api.shippable.com/')
.get('/projects/5444c5ecb904a4b21567b0ff/branchRunStatus')
.reply(200, '[{ "branchName": "master", "statusCode": 63 }]')
)
.expectBadge({ label: 'shippable', message: 'invalid response data' })
t.create('build status (no branch redirect)')
.get('/5444c5ecb904a4b21567b0ff.svg')
.expectRedirect('/shippable/5444c5ecb904a4b21567b0ff/master.svg')

View File

@@ -20,7 +20,7 @@ t.create('non existent repo')
})
t.create('valid target manifest path')
.get('/snyk/snyk/test/fixtures/demo-os/package.json.json')
.get('/snyk/vulndb-fixtures/packages/cli/0.1.0/package.json.json')
.timeout(20000)
.expectBadge({
label: 'vulnerabilities',

View File

@@ -205,7 +205,7 @@ class SteamFileSize extends SteamFileService {
}
static render({ fileSize }) {
return { message: prettyBytes(fileSize), color: 'informational' }
return { message: prettyBytes(fileSize), color: 'brightgreen' }
}
async onRequest({ response }) {

View File

@@ -1,111 +0,0 @@
import Joi from 'joi'
import { BaseJsonService } from '../index.js'
import {
testResultQueryParamSchema,
renderTestResultBadge,
} from '../test-results.js'
import { nonNegativeInteger } from '../../services/validators.js'
const commonAttrs = {
namedParams: {
provider: 'github',
org: 'tasdemo',
repo: 'axios',
},
queryParams: {
passed_label: 'passed',
failed_label: 'failed',
skipped_label: 'skipped',
compact_message: null,
},
}
const schema = Joi.object({
badge: Joi.object({
passed: nonNegativeInteger,
failed: nonNegativeInteger,
skipped: nonNegativeInteger,
total_tests: nonNegativeInteger,
status: Joi.string().required(),
}).required(),
}).required()
export default class TasBuildStatus extends BaseJsonService {
static category = 'test-results'
static route = {
base: 'tas/tests',
pattern: ':provider/:org/:repo',
queryParamSchema: testResultQueryParamSchema,
}
static examples = [
{
title: 'TAS Tests',
staticPreview: this.render({
passed: 20,
failed: 1,
skipped: 1,
total: 22,
}),
...commonAttrs,
},
]
static defaultBadgeData = { label: 'tests' }
static render({
passed,
failed,
skipped,
total,
passedLabel,
failedLabel,
skippedLabel,
isCompact,
}) {
return renderTestResultBadge({
passed,
failed,
skipped,
total,
passedLabel,
failedLabel,
skippedLabel,
isCompact,
})
}
async fetch({ provider, org, repo }) {
return this._requestJson({
schema,
url: `https://api.tas.lambdatest.com/repo/badge?git_provider=${provider}&org=${org}&repo=${repo}`,
errorMessages: {
401: 'private project not supported',
404: 'project not found',
},
})
}
async handle(
{ provider, org, repo },
{
compact_message: compactMessage,
passed_label: passedLabel,
failed_label: failedLabel,
skipped_label: skippedLabel,
}
) {
const { badge } = await this.fetch({ provider, org, repo })
return this.constructor.render({
passed: badge.passed,
failed: badge.failed,
skipped: badge.skipped,
total: badge.total_tests,
passedLabel,
failedLabel,
skippedLabel,
isCompact: compactMessage !== undefined,
})
}
}

View File

@@ -1,52 +0,0 @@
import { createServiceTester } from '../tester.js'
import {
isDefaultTestTotals,
isCustomTestTotals,
isCustomCompactTestTotals,
} from '../test-validators.js'
export const t = await createServiceTester()
t.create('Test status')
.get('/github/tasdemo/axios.json')
.expectBadge({ label: 'tests', message: isDefaultTestTotals })
t.create('Test status with custom labels')
.get('/github/tasdemo/axios.json', {
qs: {
passed_label: 'good',
failed_label: 'bad',
skipped_label: 'n/a',
},
})
.expectBadge({ label: 'tests', message: isCustomTestTotals })
t.create('Test status with compact message and custom labels')
.get('/github/tasdemo/axios.json', {
qs: {
compact_message: null,
passed_label: '💃',
failed_label: '🤦‍♀️',
skipped_label: '🤷',
},
})
.expectBadge({
label: 'tests',
message: isCustomCompactTestTotals,
})
t.create('Test status on project that does not exist')
.get('/github/tasdemo/doesntexist.json')
.expectBadge({
label: 'tests',
message: 'project not found',
color: 'red',
})
t.create('Test status on private project')
.get('/github/tasdemo/nexe-private.json')
.expectBadge({
label: 'tests',
message: 'private project not supported',
color: 'lightgrey',
})

View File

@@ -0,0 +1,16 @@
import { redirector } from '../index.js'
export default [
redirector({
category: 'coverage',
route: {
base: 'teamcity/coverage',
pattern: ':protocol(http|https)/:hostAndPath(.+)/:buildId',
},
transformPath: ({ buildId }) => `/teamcity/coverage/${buildId}`,
transformQueryParams: ({ protocol, hostAndPath }) => ({
server: `${protocol}://${hostAndPath}`,
}),
dateAdded: new Date('2019-09-15'),
}),
]

View File

@@ -0,0 +1,15 @@
import { ServiceTester } from '../tester.js'
export const t = new ServiceTester({
id: 'TeamCityCoverageRedirect',
title: 'TeamCityCoverageRedirect',
pathPrefix: '/teamcity/coverage',
})
t.create('coverage')
.get('/https/teamcity.jetbrains.com/ReactJSNet_PullRequests.svg')
.expectRedirect(
`/teamcity/coverage/ReactJSNet_PullRequests.svg?server=${encodeURIComponent(
'https://teamcity.jetbrains.com'
)}`
)

View File

@@ -74,12 +74,12 @@ function latestMaybeSemVer(versions, pre) {
try {
// coerce to string then lowercase otherwise alpha > RC
version = versions.sort((a, b) =>
semver.compareBuild(
semver.rcompare(
`${a}`.toLowerCase(),
`${b}`.toLowerCase(),
/* loose */ true
)
)[versions.length - 1]
)[0]
} catch (e) {
version = latestDottedVersion(versions)
}
@@ -152,16 +152,11 @@ function rangeStart(v) {
return range.set[0][0].semver.version
}
function renderVersionBadge({
version,
tag,
defaultLabel,
versionFormatter = versionColor,
}) {
function renderVersionBadge({ version, tag, defaultLabel }) {
return {
label: tag ? `${defaultLabel}@${tag}` : undefined,
message: addv(version),
color: versionFormatter(version),
color: versionColor(version),
}
}

View File

@@ -118,9 +118,6 @@ describe('Version helpers', function () {
given(['1.0.0', '1.0.2', '1.1', '1.0', 'notaversion2', '12bcde4']).expect(
'1.1'
)
// build qualifiers - https://github.com/badges/shields/issues/4172
given(['0.3.9', '0.4.0+1', '0.4.0+9']).expect('0.4.0+9')
})
test(slice, () => {

View File

@@ -99,8 +99,7 @@ const documentation = `
</ul>
</p>
<p>
This badge relies on the <a target="_blank" href="https://validator.nu/">https://validator.nu/</a> service to perform the validation.
Please refer to <a target="_blank" href="https://about.validator.nu/">https://about.validator.nu/</a> for the full documentation and Terms of service.
This badge relies on the https://validator.nu/ service to perform the validation. Please refer to https://about.validator.nu/ for the full documentation and Terms of service.
The following are required from the consumer for the badge to function.
<ul class="note">

View File

@@ -49,7 +49,7 @@ export default class Wercker extends BaseJsonService {
documentation: werckerCIDocumentation,
},
{
title: `Wercker CI Run (branch)`,
title: `Wercker CI Run`,
pattern: 'ci/:applicationId/:branch',
namedParams: {
applicationId: '559e33c8e982fc615500b357',
@@ -68,7 +68,7 @@ export default class Wercker extends BaseJsonService {
staticPreview: this.render({ result: 'passed' }),
},
{
title: `Wercker Build (branch)`,
title: `Wercker Build branch`,
pattern: 'build/:userName/:applicationName/:branch',
namedParams: {
userName: 'wercker',

View File

@@ -41,7 +41,7 @@ const notFoundSchema = Joi.object()
const pluginSchemas = Joi.alternatives(pluginSchema, notFoundSchema)
const themeSchemas = Joi.alternatives(themeSchema, notFoundSchema)
export class BaseWordpress extends BaseJsonService {
export default class BaseWordpress extends BaseJsonService {
async fetch({ extensionType, slug }) {
const url = `https://api.wordpress.org/${extensionType}s/info/1.2/`
let schemas
@@ -84,12 +84,3 @@ export class BaseWordpress extends BaseJsonService {
return json
}
}
export const documentation = `
<p>
These badges rely on an API that is no longer supported by Wordpress. You are
still free to use them, simply bear in mind that Shields.io cannot guarantee
that they'll keep on working in the future. Please also double-check the
provided slug, as an incorrect value may lead to unexpected results.
</p>
`

View File

@@ -1,6 +1,7 @@
import Joi from 'joi'
import { renderDownloadsBadge } from '../downloads.js'
import { documentation, BaseWordpress } from './wordpress-base.js'
import { NotFound } from '../index.js'
import BaseWordpress from './wordpress-base.js'
const dateSchema = Joi.object()
.pattern(Joi.date().iso(), Joi.number().integer())
@@ -57,7 +58,6 @@ function DownloadsForExtensionType(extensionType) {
title: `WordPress ${capt} Downloads`,
namedParams: { interval: 'dm', slug: exampleSlug },
staticPreview: this.render({ interval: 'dm', downloads: 200000 }),
documentation,
},
]
@@ -91,9 +91,17 @@ function DownloadsForExtensionType(extensionType) {
},
},
})
const size = Object.keys(json).length
downloads = Object.values(json).reduce(
(a, b) => parseInt(a) + parseInt(b)
)
// This check is for non-existent and brand-new plugins both having new stats.
// Non-Existent plugins results are the same as a brandspanking new plugin with no downloads.
if (downloads <= 0 && size <= 1) {
throw new NotFound({
prettyMessage: `${extensionType} not found or too new`,
})
}
}
return this.constructor.render({ interval, downloads })
@@ -119,7 +127,6 @@ function InstallsForExtensionType(extensionType) {
title: `WordPress ${capt} Active Installs`,
namedParams: { slug: exampleSlug },
staticPreview: renderDownloadsBadge({ downloads: 300000 }),
documentation,
},
]

View File

@@ -98,6 +98,34 @@ t.create('Plugin Downloads - Active | Not Found')
message: 'not found',
})
t.create('Plugin Downloads - Day | Not Found')
.get('/plugin/dd/100.json')
.expectBadge({
label: 'downloads',
message: 'plugin not found or too new',
})
t.create('Plugin Downloads - Week | Not Found')
.get('/plugin/dw/100.json')
.expectBadge({
label: 'downloads',
message: 'plugin not found or too new',
})
t.create('Plugin Downloads - Month | Not Found')
.get('/plugin/dm/100.json')
.expectBadge({
label: 'downloads',
message: 'plugin not found or too new',
})
t.create('Plugin Downloads - Year | Not Found')
.get('/plugin/dy/100.json')
.expectBadge({
label: 'downloads',
message: 'plugin not found or too new',
})
t.create('Theme Downloads - Total | Not Found')
.get('/theme/dt/100.json')
.expectBadge({
@@ -111,3 +139,31 @@ t.create('Theme Downloads - Active | Not Found')
label: 'active installs',
message: 'not found',
})
t.create('Theme Downloads - Day | Not Found')
.get('/theme/dd/100.json')
.expectBadge({
label: 'downloads',
message: 'theme not found or too new',
})
t.create('Theme Downloads - Week | Not Found')
.get('/theme/dw/100.json')
.expectBadge({
label: 'downloads',
message: 'theme not found or too new',
})
t.create('Theme Downloads - Month | Not Found')
.get('/theme/dm/100.json')
.expectBadge({
label: 'downloads',
message: 'theme not found or too new',
})
t.create('Theme Downloads - Year | Not Found')
.get('/theme/dy/100.json')
.expectBadge({
label: 'downloads',
message: 'theme not found or too new',
})

View File

@@ -2,7 +2,7 @@ import moment from 'moment'
import { InvalidResponse } from '../index.js'
import { formatDate } from '../text-formatters.js'
import { age as ageColor } from '../color-formatters.js'
import { documentation, BaseWordpress } from './wordpress-base.js'
import BaseWordpress from './wordpress-base.js'
const extensionData = {
plugin: {
@@ -35,7 +35,6 @@ function LastUpdateForType(extensionType) {
title: `WordPress ${capt} Last Updated`,
namedParams: { slug: exampleSlug },
staticPreview: this.render({ lastUpdated: '2020-08-11' }),
documentation,
},
]

View File

@@ -1,7 +1,7 @@
import { NotFound } from '../index.js'
import { addv } from '../text-formatters.js'
import { version as versionColor } from '../color-formatters.js'
import { documentation, BaseWordpress } from './wordpress-base.js'
import BaseWordpress from './wordpress-base.js'
import { versionColorForWordpressVersion } from './wordpress-version-color.js'
const extensionData = {
@@ -33,7 +33,6 @@ function WordpressRequiresVersion(extensionType) {
title: `WordPress ${capt}: Required WP Version`,
namedParams: { slug: exampleSlug },
staticPreview: this.render({ wordpressVersion: '4.8' }),
documentation,
},
]
@@ -78,7 +77,6 @@ class WordpressPluginTestedVersion extends BaseWordpress {
staticPreview: this.renderStaticPreview({
testedVersion: '4.9.8',
}),
documentation,
},
]
@@ -130,7 +128,6 @@ function RequiresPHPVersionForType(extensionType) {
title: `WordPress ${capt} Required PHP Version`,
namedParams: { slug: exampleSlug },
staticPreview: this.render({ version: '5.5' }),
documentation,
},
]

View File

@@ -1,6 +1,6 @@
import { starRating, metric } from '../text-formatters.js'
import { floorCount } from '../color-formatters.js'
import { documentation, BaseWordpress } from './wordpress-base.js'
import BaseWordpress from './wordpress-base.js'
const extensionData = {
plugin: {
@@ -38,7 +38,6 @@ function RatingForExtensionType(extensionType) {
rating: 80,
numRatings: 100,
}),
documentation,
},
]
@@ -79,7 +78,7 @@ function StarsForExtensionType(extensionType) {
staticPreview: this.render({
rating: 80,
}),
documentation,
documentation: 'There is an alias <code>/r/:slug.svg</code> as well.',
},
]

View File

@@ -1,6 +1,6 @@
import { addv } from '../text-formatters.js'
import { version as versionColor } from '../color-formatters.js'
import { documentation, BaseWordpress } from './wordpress-base.js'
import BaseWordpress from './wordpress-base.js'
function VersionForExtensionType(extensionType) {
const { capt, exampleSlug } = {
@@ -29,7 +29,6 @@ function VersionForExtensionType(extensionType) {
title: `WordPress ${capt} Version`,
namedParams: { slug: exampleSlug },
staticPreview: this.render({ version: 2.5 }),
documentation,
},
]

View File

@@ -5,7 +5,7 @@ import { nonNegativeInteger } from '../validators.js'
const documentation = `
<p>By using the YouTube badges provided by Shields.io, you are agreeing to be bound by the YouTube Terms of Service. These can be found here:
<a target="_blank" href="https://www.youtube.com/t/terms">https://www.youtube.com/t/terms</a></p>`
<code>https://www.youtube.com/t/terms</code></p>`
const schema = Joi.object({
pageInfo: Joi.object({