Compare commits
5 Commits
server-202
...
ua-debug
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
046856c056 | ||
|
|
851a30be39 | ||
|
|
785ee090a9 | ||
|
|
0002d6749e | ||
|
|
fb379c0556 |
@@ -7,6 +7,7 @@ main_steps: &main_steps
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
npm install --dry-run
|
||||
npm ci
|
||||
environment:
|
||||
# https://docs.cypress.io/guides/getting-started/installing-cypress.html#Skipping-installation
|
||||
@@ -49,6 +50,7 @@ integration_steps: &integration_steps
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
npm install --dry-run
|
||||
npm ci
|
||||
environment:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
@@ -71,6 +73,7 @@ services_steps: &services_steps
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
npm install --dry-run
|
||||
npm ci
|
||||
environment:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
@@ -113,7 +116,6 @@ package_steps: &package_steps
|
||||
MOCHA_FILE: junit/badge-maker/v12/results.xml
|
||||
NODE_VERSION: v12
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
NPM_CONFIG_ENGINE_STRICT: 'false'
|
||||
name: Run package tests on Node 12
|
||||
command: scripts/run_package_tests.sh
|
||||
|
||||
@@ -123,7 +125,6 @@ package_steps: &package_steps
|
||||
MOCHA_FILE: junit/badge-maker/v14/results.xml
|
||||
NODE_VERSION: v14
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
NPM_CONFIG_ENGINE_STRICT: 'false'
|
||||
name: Run package tests on Node 14
|
||||
command: scripts/run_package_tests.sh
|
||||
|
||||
@@ -142,33 +143,39 @@ package_steps: &package_steps
|
||||
jobs:
|
||||
main:
|
||||
docker:
|
||||
- image: cimg/node:16.15
|
||||
- image: circleci/node:16
|
||||
environment:
|
||||
NPM_CONFIG_ENGINE_STRICT: 'true'
|
||||
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
|
||||
|
||||
<<: *main_steps
|
||||
|
||||
main@node-17:
|
||||
docker:
|
||||
- image: cimg/node:17.9
|
||||
- image: circleci/node:17
|
||||
|
||||
<<: *main_steps
|
||||
|
||||
integration:
|
||||
docker:
|
||||
- image: cimg/node:16.15
|
||||
- image: circleci/node:16
|
||||
environment:
|
||||
NPM_CONFIG_ENGINE_STRICT: 'true'
|
||||
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
|
||||
- image: redis
|
||||
|
||||
<<: *integration_steps
|
||||
|
||||
integration@node-17:
|
||||
docker:
|
||||
- image: cimg/node:17.9
|
||||
- image: circleci/node:17
|
||||
- image: redis
|
||||
|
||||
<<: *integration_steps
|
||||
|
||||
danger:
|
||||
docker:
|
||||
- image: cimg/node:16.15
|
||||
- image: circleci/node:16
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
@@ -188,14 +195,17 @@ jobs:
|
||||
|
||||
frontend:
|
||||
docker:
|
||||
- image: cimg/node:16.15
|
||||
|
||||
- image: circleci/node:16
|
||||
environment:
|
||||
NPM_CONFIG_ENGINE_STRICT: 'true'
|
||||
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
npm install --dry-run
|
||||
npm ci
|
||||
environment:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
@@ -225,27 +235,31 @@ jobs:
|
||||
command: npm run build
|
||||
|
||||
package:
|
||||
machine:
|
||||
image: 'ubuntu-2004:202111-02'
|
||||
machine: true
|
||||
|
||||
<<: *package_steps
|
||||
|
||||
services:
|
||||
docker:
|
||||
- image: cimg/node:16.15
|
||||
- image: circleci/node:16
|
||||
environment:
|
||||
NPM_CONFIG_ENGINE_STRICT: 'true'
|
||||
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
|
||||
|
||||
<<: *services_steps
|
||||
|
||||
services@node-17:
|
||||
docker:
|
||||
- image: cimg/node:17.9
|
||||
- image: circleci/node:17
|
||||
|
||||
<<: *services_steps
|
||||
|
||||
e2e:
|
||||
docker:
|
||||
- image: cypress/base:16.14.0
|
||||
|
||||
- image: cypress/base:16.13.0
|
||||
environment:
|
||||
NPM_CONFIG_ENGINE_STRICT: 'true'
|
||||
NPM_CONFIG_STRICT_PEER_DEPS: 'true'
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
@@ -257,6 +271,7 @@ jobs:
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
npm install --dry-run
|
||||
npm ci
|
||||
|
||||
- run:
|
||||
|
||||
228
.github/actions/close-bot/package-lock.json
generated
vendored
228
.github/actions/close-bot/package-lock.json
generated
vendored
@@ -9,53 +9,53 @@
|
||||
"version": "0.0.0",
|
||||
"license": "CC0",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.8.2",
|
||||
"@actions/github": "^5.0.3"
|
||||
"@actions/core": "^1.6.0",
|
||||
"@actions/github": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.8.2.tgz",
|
||||
"integrity": "sha512-FXcBL7nyik8K5ODeCKlxi+vts7torOkoDAKfeh61EAkAy1HAvwn9uVzZBY0f15YcQTcZZ2/iSGBFHEuioZWfDA==",
|
||||
"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": "^2.0.1"
|
||||
"@actions/http-client": "^1.0.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/github": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.3.tgz",
|
||||
"integrity": "sha512-myjA/pdLQfhUGLtRZC/J4L1RXOG4o6aYdiEq+zr5wVVKljzbFld+xv10k1FX6IkIJtNxbAq44BdwSNpQ015P0A==",
|
||||
"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": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
"@octokit/plugin-paginate-rest": "^2.17.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
||||
"@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": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||
"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"
|
||||
"tunnel": "0.0.6"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
@@ -226,48 +226,48 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.8.2.tgz",
|
||||
"integrity": "sha512-FXcBL7nyik8K5ODeCKlxi+vts7torOkoDAKfeh61EAkAy1HAvwn9uVzZBY0f15YcQTcZZ2/iSGBFHEuioZWfDA==",
|
||||
"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": "^2.0.1"
|
||||
"@actions/http-client": "^1.0.11"
|
||||
}
|
||||
},
|
||||
"@actions/github": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.3.tgz",
|
||||
"integrity": "sha512-myjA/pdLQfhUGLtRZC/J4L1RXOG4o6aYdiEq+zr5wVVKljzbFld+xv10k1FX6IkIJtNxbAq44BdwSNpQ015P0A==",
|
||||
"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": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
"@octokit/plugin-paginate-rest": "^2.17.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
||||
"@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": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||
"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"
|
||||
"tunnel": "0.0.6"
|
||||
}
|
||||
},
|
||||
"@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",
|
||||
|
||||
4
.github/actions/close-bot/package.json
vendored
4
.github/actions/close-bot/package.json
vendored
@@ -10,7 +10,7 @@
|
||||
"author": "chris48s",
|
||||
"license": "CC0",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.8.2",
|
||||
"@actions/github": "^5.0.3"
|
||||
"@actions/core": "^1.6.0",
|
||||
"@actions/github": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
12
.github/actions/tester/action.yml
vendored
Normal file
12
.github/actions/tester/action.yml
vendored
Normal 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
10
.github/actions/tester/index.js
vendored
Normal 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
416
.github/actions/tester/package-lock.json
generated
vendored
Normal 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
16
.github/actions/tester/package.json
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@@ -36,8 +36,3 @@ updates:
|
||||
day: friday
|
||||
time: '12:00'
|
||||
open-pull-requests-limit: 99
|
||||
- package-ecosystem: 'github-actions'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: weekly
|
||||
open-pull-requests-limit: 99
|
||||
|
||||
2
.github/workflows/auto-close.yml
vendored
2
.github/workflows/auto-close.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
if: github.actor == 'dependabot[bot]'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install action dependencies
|
||||
run: cd .github/actions/close-bot && npm ci
|
||||
|
||||
11
.github/workflows/build-docker-image.yml
vendored
11
.github/workflows/build-docker-image.yml
vendored
@@ -7,19 +7,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Set Git Short SHA
|
||||
run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
tags: shieldsio/shields:pr-validation
|
||||
build-args: |
|
||||
version=${{ env.SHORT_SHA }}
|
||||
version=${GITHUB_SHA::7}
|
||||
|
||||
11
.github/workflows/create-release.yml
vendored
11
.github/workflows/create-release.yml
vendored
@@ -4,9 +4,6 @@ on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
if: |
|
||||
@@ -23,7 +20,7 @@ jobs:
|
||||
run: echo "::set-output name=date::$(date --rfc-3339=date)"
|
||||
|
||||
- name: Checkout branch "master"
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: 'master'
|
||||
|
||||
@@ -34,16 +31,16 @@ jobs:
|
||||
tag: server-${{ steps.date.outputs.date }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push snapshot release to DockerHub
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
||||
15
.github/workflows/deploy-docs.yml
vendored
15
.github/workflows/deploy-docs.yml
vendored
@@ -3,16 +3,12 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v2.3.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -22,8 +18,9 @@ jobs:
|
||||
npm run build-docs
|
||||
|
||||
- name: Deploy
|
||||
uses: JamesIves/github-pages-deploy-action@v4
|
||||
uses: JamesIves/github-pages-deploy-action@3.7.1
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: api-docs
|
||||
clean: true
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BRANCH: gh-pages
|
||||
FOLDER: api-docs
|
||||
CLEAN: true
|
||||
|
||||
6
.github/workflows/draft-release.yml
vendored
6
.github/workflows/draft-release.yml
vendored
@@ -5,16 +5,12 @@ on:
|
||||
# At 01:00 on the first day of every month
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Draft Release
|
||||
uses: ./.github/actions/draft-release
|
||||
|
||||
11
.github/workflows/enforce-dependency-review.yml
vendored
11
.github/workflows/enforce-dependency-review.yml
vendored
@@ -1,11 +0,0 @@
|
||||
name: 'Dependency Review'
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
dependency-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v3
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v1
|
||||
13
.github/workflows/publish-docker-next.yml
vendored
13
.github/workflows/publish-docker-next.yml
vendored
@@ -9,25 +9,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
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@v3
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
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
20
.github/workflows/test-build-args.yml
vendored
Normal 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 }}
|
||||
69
CHANGELOG.md
69
CHANGELOG.md
@@ -4,75 +4,6 @@ Note: this changelog is for the shields.io server. The changelog for the badge-m
|
||||
|
||||
---
|
||||
|
||||
## server-2022-06-01
|
||||
|
||||
- Update GitLab logo (2022) [#7984](https://github.com/badges/shields/issues/7984)
|
||||
- [GitHub] Added milestone property to GitHub issue details service [#7864](https://github.com/badges/shields/issues/7864)
|
||||
- [Spack] Package Manager: Update Endpoint [#7957](https://github.com/badges/shields/issues/7957)
|
||||
- Update Chocolatey API endpoint URL [#7952](https://github.com/badges/shields/issues/7952)
|
||||
- [Flathub]Add downloads badge [#7724](https://github.com/badges/shields/issues/7724)
|
||||
- replace the outdated Telegram logo with the newest [#7831](https://github.com/badges/shields/issues/7831)
|
||||
- add [PUB] points badge [#7918](https://github.com/badges/shields/issues/7918)
|
||||
- add [PUB] popularity badge [#7920](https://github.com/badges/shields/issues/7920)
|
||||
- add [PUB] likes badge [#7916](https://github.com/badges/shields/issues/7916)
|
||||
- Dependency updates
|
||||
|
||||
## server-2022-05-03
|
||||
|
||||
- [OSSFScorecard] Create scorecard badge service [#7687](https://github.com/badges/shields/issues/7687)
|
||||
- Stringify [githublanguagecount] message [#7881](https://github.com/badges/shields/issues/7881)
|
||||
- Stringify and trim whitespace from a few services [#7880](https://github.com/badges/shields/issues/7880)
|
||||
- add labels to Dockerfile [#7862](https://github.com/badges/shields/issues/7862)
|
||||
- handle missing 'fly-client-ip' [#7814](https://github.com/badges/shields/issues/7814)
|
||||
- Dependency updates
|
||||
|
||||
## server-2022-04-03
|
||||
|
||||
- Breaking change: This release updates ioredis from v4 to v5.
|
||||
If you are using redis for GitHub token pooling, redis connection strings of the form
|
||||
`redis://junkusername:authpassword@example.com:1234` will need to be updated to
|
||||
`redis://:authpassword@example.com:1234`. See the
|
||||
[ioredis upgrade guide](https://github.com/luin/ioredis/wiki/Upgrading-from-v4-to-v5)
|
||||
for further details.
|
||||
- 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)
|
||||
|
||||
@@ -9,7 +9,7 @@ COPY package.json package-lock.json /usr/src/app/
|
||||
COPY badge-maker /usr/src/app/badge-maker/
|
||||
|
||||
RUN apk add python3 make g++
|
||||
RUN npm install -g "npm@>=8"
|
||||
RUN npm install -g "npm@>=7"
|
||||
# We need dev deps to build the front end. We don't need Cypress, though.
|
||||
RUN NODE_ENV=development CYPRESS_INSTALL_BINARY=0 npm ci
|
||||
|
||||
@@ -23,8 +23,6 @@ FROM node:16-alpine
|
||||
|
||||
ARG version=dev
|
||||
ENV DOCKER_SHIELDS_VERSION=$version
|
||||
LABEL version=$version
|
||||
LABEL fly.version=$version
|
||||
|
||||
# Run the server using production configs.
|
||||
ENV NODE_ENV production
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -6,20 +6,13 @@ public:
|
||||
enabled: true
|
||||
url: https://metrics.shields.io/telegraf
|
||||
instanceIdFrom: env-var
|
||||
instanceIdEnvVarName: FLY_ALLOC_ID
|
||||
instanceIdEnvVarName: HEROKU_DYNO_ID
|
||||
envLabel: shields-production
|
||||
|
||||
ssl:
|
||||
isSecure: false
|
||||
isSecure: true
|
||||
|
||||
cors:
|
||||
allowedOrigin: ['http://shields.io', 'https://shields.io']
|
||||
|
||||
services:
|
||||
gitlab:
|
||||
authorizedOrigins: 'https://gitlab.com'
|
||||
|
||||
rasterUrl: 'https://raster.shields.io'
|
||||
userAgentBase: 'Shields.io'
|
||||
requireCloudflare: true
|
||||
requestTimeoutSeconds: 20
|
||||
|
||||
@@ -147,7 +147,6 @@ class BaseService {
|
||||
version: 300,
|
||||
debug: 60,
|
||||
downloads: 900,
|
||||
rating: 900,
|
||||
social: 900,
|
||||
}
|
||||
return cacheLengths[this.category]
|
||||
|
||||
66
core/server/public/monitor.html
Normal file
66
core/server/public/monitor.html
Normal file
@@ -0,0 +1,66 @@
|
||||
<!doctype html><meta charset=utf-8>
|
||||
<title> Shields.io Admin Monitoring Interface </title>
|
||||
<style>
|
||||
#monitorPlatform { display: none; }
|
||||
</style>
|
||||
|
||||
<div id=passwordRequest>
|
||||
<p> Please enter your admin secret here:
|
||||
<input type=password id=secretInput>
|
||||
</div>
|
||||
<div id=monitorPlatform>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
let network;
|
||||
const onLoad = function() {
|
||||
const secretInput = document.getElementById('secretInput');
|
||||
const onSecretChange = function() {
|
||||
const secret = secretInput.value;
|
||||
const authentication = `monitor:${secret}`;
|
||||
const headers = new Headers({
|
||||
Authorization: `Basic ${btoa(authentication)}`
|
||||
})
|
||||
fetch('/sys/network', {headers})
|
||||
.then(res => res.json())
|
||||
.then(networkData => {
|
||||
network = networkData;
|
||||
// Show monitor platform.
|
||||
monitorPlatform.style.display = 'block';
|
||||
passwordRequest.parentNode.removeChild(passwordRequest);
|
||||
|
||||
// Show logs for each server.
|
||||
network.ips.forEach(ip => {
|
||||
const logger = document.createElement('div');
|
||||
const pre = document.createElement('pre');
|
||||
logger.textContent = ip;
|
||||
logger.appendChild(pre);
|
||||
monitorPlatform.appendChild(logger);
|
||||
|
||||
// Set up the websocket.
|
||||
const setUpWebsocket = () => {
|
||||
const websocket = new WebSocket(
|
||||
(window.location.protocol === 'http:' ? 'ws' : 'wss') + '://' +
|
||||
ip + ':' + window.location.port + '/sys/logs');
|
||||
websocket.addEventListener('message', event => {
|
||||
pre.textContent += event.data + '\n';
|
||||
});
|
||||
websocket.addEventListener('close', () => {
|
||||
setTimeout(setUpWebsocket, 100);
|
||||
});
|
||||
websocket.addEventListener('open', () => {
|
||||
websocket.send(JSON.stringify({secret}));
|
||||
});
|
||||
};
|
||||
setUpWebsocket();
|
||||
});
|
||||
})
|
||||
.catch(alert)
|
||||
};
|
||||
secretInput.addEventListener('change', onSecretChange);
|
||||
};
|
||||
|
||||
addEventListener('DOMContentLoaded', onLoad);
|
||||
}());
|
||||
</script>
|
||||
@@ -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,21 +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']
|
||||
? req.headers['fly-client-ip']
|
||||
: req.socket.remoteAddress
|
||||
} 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())
|
||||
|
||||
@@ -25,7 +25,7 @@ and learn about the [GitHub workflow](http://try.github.io/).
|
||||
|
||||
#### Node, NPM
|
||||
|
||||
Node >=16 and NPM >=8 is required. If you don't already have them,
|
||||
Node >=16 and NPM >=7 is required. If you don't already have them,
|
||||
install node and npm: https://nodejs.org/en/download/
|
||||
|
||||
### Setup a dev install
|
||||
|
||||
@@ -40,7 +40,7 @@ If you are submitting a pull request for a custom logo, please:
|
||||
- Install SVGO
|
||||
- With npm: `npm install -g svgo`
|
||||
- With Homebrew: `brew install svgo`
|
||||
- Run the following command `svgo --precision=3 icon.svg -o icon.min.svg`
|
||||
- Run the following command `svgo --precision=3 icon.svg icon.min.svg`
|
||||
- Check if there is a loss of quality in the output, if so increase the precision.
|
||||
- The [SVGOMG Online Tool][svgomg]
|
||||
- Click "Open SVG" and select an SVG file.
|
||||
|
||||
@@ -16,8 +16,9 @@ Production hosting is managed by the Shields ops team:
|
||||
|
||||
| Component | Subcomponent | People with access |
|
||||
| ----------------------------- | ------------------------------- | --------------------------------------------------------------- |
|
||||
| shields-io-production | Full access | @calebcartwright, @chris48s, @paulmelnikow |
|
||||
| shields-io-production | Access management | @calebcartwright, @chris48s, @paulmelnikow |
|
||||
| shields-production-us | Account owner | @calebcartwright, @paulmelnikow |
|
||||
| shields-production-us | Full access | @calebcartwright, @chris48s, @paulmelnikow, @pyvesb |
|
||||
| shields-production-us | Access management | @calebcartwright, @chris48s, @paulmelnikow, @pyvesb |
|
||||
| Compose.io Redis | Account owner | @paulmelnikow |
|
||||
| Compose.io Redis | Account access | @paulmelnikow |
|
||||
| Compose.io Redis | Database connection credentials | @calebcartwright, @chris48s, @paulmelnikow, @pyvesb |
|
||||
@@ -94,10 +95,13 @@ The raster server `raster.shields.io` (a.k.a. the rasterizing proxy) is
|
||||
hosted on Heroku. It's managed in the
|
||||
[squint](https://github.com/badges/squint/) repo.
|
||||
|
||||
### Fly.io Deployment
|
||||
### Heroku Deployment
|
||||
|
||||
Both the badge server and frontend are served from Fly.io. Deployments are
|
||||
triggered using GitHub actions in a private repo.
|
||||
Both the badge server and frontend are served from Heroku.
|
||||
|
||||
After merging a commit to master, heroku should create a staging deploy. Check this has deployed correctly in the `shields-staging` pipeline and review https://shields-staging.herokuapp.com/
|
||||
|
||||
If we're happy with it, "promote to production". This will deploy what's on staging to the `shields-production-eu` and `shields-production-us` pieplines.
|
||||
|
||||
## DNS
|
||||
|
||||
@@ -105,15 +109,19 @@ DNS is registered with [DNSimple][].
|
||||
|
||||
[dnsimple]: https://dnsimple.com/
|
||||
|
||||
## Logs
|
||||
|
||||
Logs can be retrieved [from heroku](https://devcenter.heroku.com/articles/logging#log-retrieval).
|
||||
|
||||
## Error reporting
|
||||
|
||||
[Error reporting][sentry] is one of the most useful tools we have for monitoring
|
||||
the server. It's generously donated by [Sentry][sentry home]. We bundle
|
||||
[`@sentry/node`][sentry-node] into the application, and the Sentry DSN is configured
|
||||
via `local-shields-io-production.yml` (see [documentation][sentry configuration]).
|
||||
[`raven`][raven] into the application, and the Sentry DSN is configured via
|
||||
`local-shields-io-production.yml` (see [documentation][sentry configuration]).
|
||||
|
||||
[sentry]: https://sentry.io/shields/
|
||||
[sentry-node]: https://www.npmjs.com/package/@sentry/node
|
||||
[raven]: https://www.npmjs.com/package/raven
|
||||
[sentry home]: https://sentry.io/shields/
|
||||
[sentry configuration]: https://github.com/badges/shields/blob/master/doc/self-hosting.md#sentry
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ machine.
|
||||
|
||||
If you want to host PNG badges, you can also self-host a [raster server][]
|
||||
which points to your badge server. It's a docker container. We host it on
|
||||
Fly.io but should be possible to host on a wide variety of platforms.
|
||||
Heroku but should be possible to host on a wide variety of platforms.
|
||||
|
||||
- In your raster instance, set `BASE_URL` to your Shields instance, e.g.
|
||||
`https://shields.example.co`.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="93 93 194 194"><defs><style>.b{fill:#fc6d26}</style></defs><path style="fill:#e24329" d="m282.83 170.73-.27-.69-26.14-68.22a6.81 6.81 0 0 0-2.69-3.24 7 7 0 0 0-8 .43 7 7 0 0 0-2.32 3.52l-17.65 54h-71.47l-17.65-54a6.86 6.86 0 0 0-2.32-3.53 7 7 0 0 0-8-.43 6.87 6.87 0 0 0-2.69 3.24L97.44 170l-.26.69a48.54 48.54 0 0 0 16.1 56.1l.09.07.24.17 39.82 29.82 19.7 14.91 12 9.06a8.07 8.07 0 0 0 9.76 0l12-9.06 19.7-14.91 40.06-30 .1-.08a48.56 48.56 0 0 0 16.08-56.04Z"/><path class="b" d="m282.83 170.73-.27-.69a88.3 88.3 0 0 0-35.15 15.8L190 229.25c19.55 14.79 36.57 27.64 36.57 27.64l40.06-30 .1-.08a48.56 48.56 0 0 0 16.1-56.08Z"/><path style="fill:#fca326" d="m153.43 256.89 19.7 14.91 12 9.06a8.07 8.07 0 0 0 9.76 0l12-9.06 19.7-14.91S209.55 244 190 229.25c-19.55 14.75-36.57 27.64-36.57 27.64Z"/><path class="b" d="M132.58 185.84A88.19 88.19 0 0 0 97.44 170l-.26.69a48.54 48.54 0 0 0 16.1 56.1l.09.07.24.17 39.82 29.82L190 229.21Z"/></svg>
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M23.956 13.587l-1.344-4.133a4549.814 4549.814 0 0 0-2.663-8.189.456.456 0 0 0-.87 0l-2.658 8.189H7.585L4.92 1.265a.456.456 0 0 0-.87 0A4549.814 4549.814 0 0 0 .044 13.587a.908.908 0 0 0 .336 1.02L12 23.054l11.62-8.447a.908.908 0 0 0 .336-1.02" fill="#fc6d26"/><path d="M12 23.054l4.421-13.6H7.58z" fill="#e24329"/><path d="M7.579 9.454H1.388L12 23.054z" fill="#fc6d26"/><path d="M1.388 9.454L.044 13.587a.908.908 0 0 0 .336 1.02L12 23.054z" fill="#fca326"/><path d="M7.579 9.454L4.92 1.265a.456.456 0 0 0-.87 0L1.388 9.454z" fill="#e24329"/><path d="M16.421 9.454h6.191L12 23.054z" fill="#fc6d26"/><path d="M22.612 9.454l1.344 4.133a.908.908 0 0 1-.336 1.02L12 23.054z" fill="#fca326"/><path d="M16.421 9.454l2.658-8.189a.456.456 0 0 1 .87 0l2.663 8.189z" fill="#e24329"/></svg>
|
||||
|
Before Width: | Height: | Size: 986 B After Width: | Height: | Size: 847 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 24c6.627 0 12-5.373 12-12S18.627 0 12 0 0 5.373 0 12s5.373 12 12 12Z" fill="url(#a)"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5.425 11.871a796.414 796.414 0 0 1 6.994-3.018c3.328-1.388 4.027-1.628 4.477-1.638.1 0 .32.02.47.14.12.1.15.23.17.33.02.1.04.31.02.47-.18 1.898-.96 6.504-1.36 8.622-.17.9-.5 1.199-.819 1.229-.7.06-1.229-.46-1.898-.9-1.06-.689-1.649-1.119-2.678-1.798-1.19-.78-.42-1.209.26-1.908.18-.18 3.247-2.978 3.307-3.228.01-.03.01-.15-.06-.21-.07-.06-.17-.04-.25-.02-.11.02-1.788 1.14-5.056 3.348-.48.33-.909.49-1.299.48-.43-.01-1.248-.24-1.868-.44-.75-.24-1.349-.37-1.299-.79.03-.22.33-.44.89-.669Z" fill="#fff"/><defs><linearGradient id="a" x1="11.99" y1="0" x2="11.99" y2="23.81" gradientUnits="userSpaceOnUse"><stop stop-color="#2AABEE"/><stop offset="1" stop-color="#229ED9"/></linearGradient></defs></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="12" fill="#2ca5e0"/><path d="M9.8 17.5c-.389 0-.323-.147-.457-.517L8.2 13.221 17 8" fill="#a9c9dd"/><path d="M9.8 17.5c.3 0 .433-.137.6-.3l1.6-1.556-1.996-1.203" fill="#c8daea"/><path d="M10.004 14.441l4.836 3.573c.552.304.95.147 1.088-.512l1.968-9.277c.202-.808-.308-1.174-.836-.935L5.501 11.748c-.789.316-.784.756-.144.952l2.967.926 6.867-4.332c.324-.197.622-.091.377.125" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 909 B After Width: | Height: | Size: 481 B |
4487
package-lock.json
generated
4487
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
113
package.json
113
package.json
@@ -21,29 +21,28 @@
|
||||
"url": "https://github.com/badges/shields"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/lato": "^4.5.8",
|
||||
"@fontsource/lekton": "^4.5.9",
|
||||
"@renovate/pep440": "^1.0.0",
|
||||
"@sentry/node": "^6.19.7",
|
||||
"@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",
|
||||
"glob": "^8.0.3",
|
||||
"fast-xml-parser": "^4.0.2",
|
||||
"glob": "^7.2.0",
|
||||
"global-agent": "^3.0.0",
|
||||
"got": "^12.1.0",
|
||||
"got": "^12.0.1",
|
||||
"graphql": "^15.6.1",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"ioredis": "5.0.5",
|
||||
"ioredis": "4.28.4",
|
||||
"joi": "17.6.0",
|
||||
"joi-extension-semver": "5.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
@@ -51,17 +50,17 @@
|
||||
"lodash.countby": "^4.6.0",
|
||||
"lodash.groupby": "^4.6.0",
|
||||
"lodash.times": "^4.3.2",
|
||||
"moment": "^2.29.3",
|
||||
"moment": "^2.29.1",
|
||||
"node-env-flag": "^0.1.0",
|
||||
"parse-link-header": "^2.0.0",
|
||||
"path-to-regexp": "^6.2.1",
|
||||
"pretty-bytes": "^6.0.0",
|
||||
"path-to-regexp": "^6.2.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.7",
|
||||
"simple-icons": "6.23.0",
|
||||
"semver": "~7.3.5",
|
||||
"simple-icons": "6.8.0",
|
||||
"webextension-store-meta": "^1.0.5",
|
||||
"xmldom": "~0.6.0",
|
||||
"xpath": "~0.0.32"
|
||||
@@ -141,88 +140,88 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.18.2",
|
||||
"@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.1",
|
||||
"@types/lodash.debounce": "^4.0.7",
|
||||
"@types/lodash.groupby": "^4.6.7",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/chai": "^4.3.0",
|
||||
"@types/lodash.debounce": "^4.0.6",
|
||||
"@types/lodash.groupby": "^4.6.6",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/node": "^16.7.10",
|
||||
"@types/react-helmet": "^6.1.5",
|
||||
"@types/react-modal": "^3.13.1",
|
||||
"@types/react-select": "^4.0.17",
|
||||
"@types/styled-components": "5.1.25",
|
||||
"@typescript-eslint/eslint-plugin": "^5.26.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.14.0",
|
||||
"c8": "^7.11.3",
|
||||
"caller": "^1.1.0",
|
||||
"babel-preset-gatsby": "^2.5.1",
|
||||
"c8": "^7.11.0",
|
||||
"caller": "^1.0.1",
|
||||
"chai": "^4.3.6",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"chai-datetime": "^1.8.0",
|
||||
"chai-string": "^1.4.0",
|
||||
"child-process-promise": "^2.2.1",
|
||||
"clipboard-copy": "^4.0.1",
|
||||
"concurrently": "^7.2.1",
|
||||
"cypress": "^9.7.0",
|
||||
"danger": "^11.0.7",
|
||||
"concurrently": "^7.0.0",
|
||||
"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.26.0",
|
||||
"eslint-plugin-jsdoc": "^39.3.2",
|
||||
"eslint-plugin-mocha": "^10.0.5",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"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.30.0",
|
||||
"eslint-plugin-react-hooks": "^4.5.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.4.2",
|
||||
"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",
|
||||
"nock": "13.2.4",
|
||||
"node-mocks-http": "^1.11.0",
|
||||
"nodemon": "^2.0.16",
|
||||
"nodemon": "^2.0.15",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"open-cli": "^7.0.1",
|
||||
"portfinder": "^1.0.28",
|
||||
"prettier": "2.6.2",
|
||||
"prettier": "2.5.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-error-overlay": "^6.0.11",
|
||||
"react-error-overlay": "^6.0.10",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-modal": "^3.15.1",
|
||||
"react-modal": "^3.14.4",
|
||||
"react-pose": "^4.0.10",
|
||||
"react-select": "^4.3.1",
|
||||
"read-all-stdin-sync": "^1.0.5",
|
||||
@@ -230,19 +229,19 @@
|
||||
"rimraf": "^3.0.2",
|
||||
"sazerac": "^2.0.0",
|
||||
"simple-git-hooks": "^2.7.0",
|
||||
"sinon": "^14.0.0",
|
||||
"sinon": "^13.0.1",
|
||||
"sinon-chai": "^3.7.0",
|
||||
"snap-shot-it": "^7.9.6",
|
||||
"start-server-and-test": "1.14.0",
|
||||
"styled-components": "^5.3.5",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"tsd": "^0.20.0",
|
||||
"typescript": "^4.7.2",
|
||||
"styled-components": "^5.3.3",
|
||||
"ts-mocha": "^9.0.2",
|
||||
"tsd": "^0.19.1",
|
||||
"typescript": "^4.5.5",
|
||||
"url": "^0.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.13.0",
|
||||
"npm": ">=8.0.0"
|
||||
"node": "^16.13.0",
|
||||
"npm": ">=7.0.0"
|
||||
},
|
||||
"type": "module",
|
||||
"collective": {
|
||||
|
||||
@@ -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}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@ class AmoWeeklyDownloads extends BaseAmoService {
|
||||
},
|
||||
]
|
||||
|
||||
static _cacheLength = 21600
|
||||
|
||||
static defaultBadgeData = { label: 'downloads' }
|
||||
|
||||
static render({ downloads }) {
|
||||
|
||||
@@ -23,8 +23,6 @@ export default class AmoRating extends BaseAmoService {
|
||||
},
|
||||
]
|
||||
|
||||
static _cacheLength = 7200
|
||||
|
||||
static render({ format, rating }) {
|
||||
rating = Math.round(rating)
|
||||
return {
|
||||
|
||||
@@ -14,8 +14,6 @@ export default class AmoUsers extends BaseAmoService {
|
||||
},
|
||||
]
|
||||
|
||||
static _cacheLength = 21600
|
||||
|
||||
static defaultBadgeData = { label: 'users' }
|
||||
|
||||
static render({ users: downloads }) {
|
||||
|
||||
@@ -21,8 +21,8 @@ export default class Bitrise extends BaseJsonService {
|
||||
static examples = [
|
||||
{
|
||||
title: 'Bitrise',
|
||||
namedParams: { appId: '3ff11fe8457bd304', branch: 'master' },
|
||||
queryParams: { token: 'lESRN9rEFFfDq92JtXs_jw' },
|
||||
namedParams: { appId: 'cde737473028420d', branch: 'master' },
|
||||
queryParams: { token: 'GCIdEzacE4GW32jLVrZb7A' },
|
||||
staticPreview: this.render({ status: 'success' }),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -3,14 +3,14 @@ import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('deploy status')
|
||||
.get('/3ff11fe8457bd304.json?token=lESRN9rEFFfDq92JtXs_jw')
|
||||
.get('/cde737473028420d.json?token=GCIdEzacE4GW32jLVrZb7A')
|
||||
.expectBadge({
|
||||
label: 'bitrise',
|
||||
message: isBuildStatus,
|
||||
})
|
||||
|
||||
t.create('deploy status with branch')
|
||||
.get('/3ff11fe8457bd304/master.json?token=lESRN9rEFFfDq92JtXs_jw')
|
||||
.get('/cde737473028420d/master.json?token=GCIdEzacE4GW32jLVrZb7A')
|
||||
.expectBadge({
|
||||
label: 'bitrise',
|
||||
message: isBuildStatus,
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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, () => {
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
/**
|
||||
* Common functions and schemas for tasks related to build status.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import Joi from 'joi'
|
||||
|
||||
const greenStatuses = [
|
||||
@@ -56,23 +50,8 @@ const allStatuses = greenStatuses
|
||||
.concat(redStatuses)
|
||||
.concat(otherStatuses)
|
||||
|
||||
/**
|
||||
* Joi schema for validating Build Status.
|
||||
* Checks if the build status is present in the list of allowed build status.
|
||||
*
|
||||
* @type {object}
|
||||
*/
|
||||
const isBuildStatus = Joi.equal(...allStatuses)
|
||||
|
||||
/**
|
||||
* Handles rendering concerns of badges that display build status.
|
||||
* Determines the message and color of the badge according to the build status.
|
||||
*
|
||||
* @param {object} attrs Refer to individual attributes
|
||||
* @param {string} [attrs.label] If provided then badge label is set to this value
|
||||
* @param {string} attrs.status Build status
|
||||
* @returns {object} Badge with label, message and color properties
|
||||
*/
|
||||
function renderBuildStatusBadge({ label, status }) {
|
||||
let message
|
||||
let color
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createServiceFamily } from '../nuget/nuget-v2-service-family.js'
|
||||
export default createServiceFamily({
|
||||
defaultLabel: 'chocolatey',
|
||||
serviceBaseUrl: 'chocolatey',
|
||||
apiBaseUrl: 'https://community.chocolatey.org/api/v2',
|
||||
apiBaseUrl: 'https://www.chocolatey.org/api/v2',
|
||||
odataFormat: 'json',
|
||||
title: 'Chocolatey',
|
||||
examplePackageName: 'git',
|
||||
|
||||
@@ -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' }),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -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}`,
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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}`,
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
/**
|
||||
* Commonly-used functions for determining the colour to use for a badge,
|
||||
* including colours based off download count, version number, etc.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import moment from 'moment'
|
||||
import pep440 from '@renovate/pep440'
|
||||
|
||||
/**
|
||||
* Determines the color used for a badge based on version.
|
||||
*
|
||||
* @param {string|number} version Version used for determining badge color
|
||||
* @returns {string} Badge color
|
||||
*/
|
||||
function version(version) {
|
||||
if (typeof version !== 'string' && typeof version !== 'number') {
|
||||
throw new Error(`Can't generate a version color for ${version}`)
|
||||
@@ -30,35 +20,6 @@ function version(version) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color used for a badge based on PEP440 versioning.
|
||||
*
|
||||
* @param {string|number} version Version used for determining badge color
|
||||
* @returns {string} Badge color
|
||||
*/
|
||||
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'
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color used for a badge by comparing the value and floor count values.
|
||||
* The color can vary from red to bright green depending on the range the value lies in.
|
||||
* Decreasing the value will shift the color towards red.
|
||||
* Increasing the value will shift the color towards bright green.
|
||||
*
|
||||
* @param {number} value Current value
|
||||
* @param {number} yellow Yellow color threshold, should be greater than 0
|
||||
* @param {number} yellowgreen Yellowgreen color threshold, should be greater than yellow
|
||||
* @param {number} green Green color threshold, should be greater than yellowgreen
|
||||
* @returns {string} Badge color
|
||||
*/
|
||||
function floorCount(value, yellow, yellowgreen, green) {
|
||||
if (value <= 0) {
|
||||
return 'red'
|
||||
@@ -73,37 +34,14 @@ function floorCount(value, yellow, yellowgreen, green) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color used for a badge by comparing the download count and floor values.
|
||||
* The color varies from red to bright green as the download count increases.
|
||||
*
|
||||
* @param {number} downloads Download count
|
||||
* @returns {string} Badge color
|
||||
*/
|
||||
function downloadCount(downloads) {
|
||||
return floorCount(downloads, 10, 100, 1000)
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color used for a badge by comparing percentage and floor values.
|
||||
* The color varies from red to bright green as the percentage increases.
|
||||
*
|
||||
* @param {number} percentage Percentage value
|
||||
* @returns {string} Badge color
|
||||
*/
|
||||
function coveragePercentage(percentage) {
|
||||
return floorCount(percentage, 80, 90, 100)
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color used for a badge by matching score with grade values.
|
||||
* The color varies from bright green to red as the score decreases.
|
||||
* The score can be one of the following grade value: ['A', 'B', 'C', 'D', 'E'].
|
||||
* The color defaults to red if the score does not matches with any of the grade values.
|
||||
*
|
||||
* @param {string} score Score value
|
||||
* @returns {string} Badge color
|
||||
*/
|
||||
function letterScore(score) {
|
||||
if (score === 'A') {
|
||||
return 'brightgreen'
|
||||
@@ -120,18 +58,6 @@ function letterScore(score) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a callback function that determines badge color from the colors array.
|
||||
* If the colors array is provided then for n steps, there should be n + 1 color.
|
||||
* If the colors array is not provided then it is chosen from the default colors array
|
||||
* according to the size of the steps array.
|
||||
*
|
||||
* @param {number[]} steps Steps array
|
||||
* @param {string[]} colors Colors array. If provided, should be of length steps.length + 1
|
||||
* @param {boolean} reversed If true then the colors array will be considered in reverse order
|
||||
* @returns {function(number): string} Function that finds the step index by comparing value
|
||||
* with steps array and returns color from colors array for the corresponding step index
|
||||
*/
|
||||
function colorScale(steps, colors, reversed) {
|
||||
if (steps === undefined) {
|
||||
throw Error('When invoking colorScale, steps should be provided.')
|
||||
@@ -172,14 +98,6 @@ function colorScale(steps, colors, reversed) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color used for a badge according to the age.
|
||||
* Age is calculated as days elapsed till current date.
|
||||
* The color varies from bright green to red as the age increases.
|
||||
*
|
||||
* @param {string} date Date string
|
||||
* @returns {string} Badge color
|
||||
*/
|
||||
function age(date) {
|
||||
const colorByAge = colorScale([7, 30, 180, 365, 730], undefined, true)
|
||||
const daysElapsed = moment().diff(moment(date), 'days')
|
||||
@@ -188,7 +106,6 @@ function age(date) {
|
||||
|
||||
export {
|
||||
version,
|
||||
pep440VersionColor,
|
||||
downloadCount,
|
||||
coveragePercentage,
|
||||
floorCount,
|
||||
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
})
|
||||
@@ -1,18 +1,5 @@
|
||||
/**
|
||||
* Common functions and utilities for tasks related to contributor count.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import { metric } from './text-formatters.js'
|
||||
|
||||
/**
|
||||
* Determines the color used for a badge based on the contributor count.
|
||||
* The color varies from red to bright green as the contributor count increases.
|
||||
*
|
||||
* @param {number} contributorCount Contributor count
|
||||
* @returns {string} Badge color
|
||||
*/
|
||||
function contributorColor(contributorCount) {
|
||||
if (contributorCount > 2) {
|
||||
return 'brightgreen'
|
||||
@@ -23,15 +10,6 @@ function contributorColor(contributorCount) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles rendering concerns of badges that display contributor count.
|
||||
* Determines the message and color of the badge according to the contributor count.
|
||||
*
|
||||
* @param {object} attrs Refer to individual attributes
|
||||
* @param {string} [attrs.label] If provided then badge label is set to this value
|
||||
* @param {number} attrs.contributorCount Contributor count
|
||||
* @returns {object} Badge with label, message and color properties
|
||||
*/
|
||||
function renderContributorBadge({ label, contributorCount }) {
|
||||
return {
|
||||
label,
|
||||
|
||||
9
services/deprecation-helpers.js
Normal file
9
services/deprecation-helpers.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Deprecated } from './index.js'
|
||||
|
||||
function enforceDeprecation(effectiveDate) {
|
||||
if (Date.now() >= effectiveDate.getTime()) {
|
||||
throw new Deprecated()
|
||||
}
|
||||
}
|
||||
|
||||
export { enforceDeprecation }
|
||||
15
services/deprecation-helpers.spec.js
Normal file
15
services/deprecation-helpers.spec.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { expect } from 'chai'
|
||||
import { Deprecated } from '../core/base-service/errors.js'
|
||||
import { enforceDeprecation } from './deprecation-helpers.js'
|
||||
|
||||
describe('enforceDeprecation', function () {
|
||||
it('throws Deprecated for a date in the past', function () {
|
||||
expect(() => enforceDeprecation(new Date())).to.throw(Deprecated)
|
||||
})
|
||||
|
||||
it('does not throw for a date in the future', function () {
|
||||
expect(() =>
|
||||
enforceDeprecation(new Date(Date.now() + 10000))
|
||||
).not.to.throw()
|
||||
})
|
||||
})
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { renderDownloadsBadge } from '../downloads.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
installs_total: Joi.number().integer().required(),
|
||||
}).required()
|
||||
|
||||
export default class FlathubDownloads extends BaseJsonService {
|
||||
static category = 'downloads'
|
||||
static route = { base: 'flathub/downloads', pattern: ':packageName' }
|
||||
static examples = [
|
||||
{
|
||||
title: 'Flathub',
|
||||
namedParams: {
|
||||
packageName: 'org.mozilla.firefox',
|
||||
},
|
||||
staticPreview: renderDownloadsBadge({ downloads: '277136' }),
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'installs' }
|
||||
|
||||
async handle({ packageName }) {
|
||||
const data = await this._requestJson({
|
||||
schema,
|
||||
url: `https://flathub.org/api/v2/stats/${encodeURIComponent(
|
||||
packageName
|
||||
)}`,
|
||||
})
|
||||
return renderDownloadsBadge({ downloads: data.installs_total })
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { isMetric } from '../test-validators.js'
|
||||
import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('Flathub Downloads (valid)')
|
||||
.get('/org.mozilla.firefox.json')
|
||||
.expectBadge({
|
||||
label: 'installs',
|
||||
message: isMetric,
|
||||
})
|
||||
|
||||
t.create('Flathub Downloads (not found)')
|
||||
.get('/not.a.package.json')
|
||||
.expectBadge({ label: 'installs', message: 'not found' })
|
||||
@@ -1,6 +1,5 @@
|
||||
import Joi from 'joi'
|
||||
import { floorCount as floorCountColor } from '../color-formatters.js'
|
||||
import { metric } from '../text-formatters.js'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
|
||||
const ownerSchema = Joi.array().required()
|
||||
@@ -21,7 +20,7 @@ export default class GemOwner extends BaseJsonService {
|
||||
|
||||
static render({ count }) {
|
||||
return {
|
||||
message: metric(count),
|
||||
message: count,
|
||||
color: floorCountColor(count, 10, 50, 100),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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}`
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
@@ -58,7 +58,7 @@ export default class GithubDeployments extends GithubAuthV4Service {
|
||||
environment: 'shields-staging',
|
||||
},
|
||||
staticPreview: this.render({
|
||||
state: 'SUCCESS',
|
||||
state: 'success',
|
||||
}),
|
||||
documentation,
|
||||
},
|
||||
|
||||
@@ -140,26 +140,6 @@ const ageUpdateMap = {
|
||||
}),
|
||||
}
|
||||
|
||||
const milestoneMap = {
|
||||
schema: Joi.object({
|
||||
...commonSchemaFields,
|
||||
milestone: Joi.object({
|
||||
title: Joi.string().required(),
|
||||
}).allow(null),
|
||||
}).required(),
|
||||
transform: ({ json }) => {
|
||||
if (!json.milestone) {
|
||||
throw new InvalidResponse({ prettyMessage: 'no milestone' })
|
||||
}
|
||||
return json.milestone.title
|
||||
},
|
||||
render: ({ value }) => ({
|
||||
label: 'milestone',
|
||||
message: value,
|
||||
color: 'informational',
|
||||
}),
|
||||
}
|
||||
|
||||
const propertyMap = {
|
||||
state: stateMap,
|
||||
title: titleMap,
|
||||
@@ -168,7 +148,6 @@ const propertyMap = {
|
||||
comments: commentsMap,
|
||||
age: ageUpdateMap,
|
||||
'last-update': ageUpdateMap,
|
||||
milestone: milestoneMap,
|
||||
}
|
||||
|
||||
export default class GithubIssueDetail extends GithubAuthV3Service {
|
||||
@@ -176,7 +155,7 @@ export default class GithubIssueDetail extends GithubAuthV3Service {
|
||||
static route = {
|
||||
base: 'github',
|
||||
pattern:
|
||||
':issueKind(issues|pulls)/detail/:property(state|title|author|label|comments|age|last-update|milestone)/:user/:repo/:number([0-9]+)',
|
||||
':issueKind(issues|pulls)/detail/:property(state|title|author|label|comments|age|last-update)/:user/:repo/:number([0-9]+)',
|
||||
}
|
||||
|
||||
static examples = [
|
||||
@@ -203,7 +182,6 @@ export default class GithubIssueDetail extends GithubAuthV3Service {
|
||||
'comments',
|
||||
'age',
|
||||
'last update',
|
||||
'milestone',
|
||||
],
|
||||
documentation,
|
||||
},
|
||||
|
||||
@@ -90,14 +90,6 @@ describe('GithubIssueDetail', function () {
|
||||
message: formatDate('2019-04-02T20:09:31Z'),
|
||||
color: age('2019-04-02T20:09:31Z'),
|
||||
})
|
||||
given({
|
||||
property: 'milestone',
|
||||
value: 'MS 1',
|
||||
}).expect({
|
||||
label: 'milestone',
|
||||
message: 'MS 1',
|
||||
color: 'informational',
|
||||
})
|
||||
})
|
||||
|
||||
test(GithubIssueDetail.prototype.transform, () => {
|
||||
@@ -186,13 +178,6 @@ describe('GithubIssueDetail', function () {
|
||||
value: '2019-04-02T20:09:31Z',
|
||||
isPR: false,
|
||||
})
|
||||
given({
|
||||
property: 'milestone',
|
||||
json: { milestone: { title: 'MS 1' } },
|
||||
}).expect({
|
||||
value: 'MS 1',
|
||||
isPR: false,
|
||||
})
|
||||
})
|
||||
|
||||
context('transform()', function () {
|
||||
@@ -209,19 +194,4 @@ describe('GithubIssueDetail', function () {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
context('transform()', function () {
|
||||
it('throws InvalidResponse error when issue has no milestone', function () {
|
||||
try {
|
||||
GithubIssueDetail.prototype.transform({
|
||||
property: 'milestone',
|
||||
json: { milestone: null },
|
||||
})
|
||||
expect.fail('Expected to throw')
|
||||
} catch (e) {
|
||||
expect(e).to.be.an.instanceof(InvalidResponse)
|
||||
expect(e.prettyMessage).to.equal('no milestone')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -64,16 +64,3 @@ t.create('github pull request merge state (pull request not found)')
|
||||
label: 'issue/pull request',
|
||||
message: 'issue, pull request or repo not found',
|
||||
})
|
||||
|
||||
t.create('github issue milestone')
|
||||
.get('/issues/detail/milestone/badges/shields/4949.json')
|
||||
.expectBadge({
|
||||
label: 'milestone',
|
||||
message: 'badge-maker v3.4',
|
||||
})
|
||||
|
||||
t.create('github issue milestone (without milestone)')
|
||||
.get('/issues/detail/milestone/badges/shields/979.json')
|
||||
.expectBadge({
|
||||
message: 'no milestone',
|
||||
})
|
||||
|
||||
@@ -307,9 +307,7 @@ export default class GithubIssues extends GithubAuthV4Service {
|
||||
|
||||
return {
|
||||
label: `${labelPrefix}${labelText}${labelSuffix}`,
|
||||
message: `${metric(issueCount)}${
|
||||
messageSuffix ? ' ' : ''
|
||||
}${messageSuffix}`,
|
||||
message: `${metric(issueCount)} ${messageSuffix}`,
|
||||
color: issueCount > 0 ? 'yellow' : 'brightgreen',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { metric } from '../text-formatters.js'
|
||||
import { BaseGithubLanguage } from './github-languages-base.js'
|
||||
import { documentation } from './github-helpers.js'
|
||||
|
||||
@@ -21,7 +20,7 @@ export default class GithubLanguageCount extends BaseGithubLanguage {
|
||||
|
||||
static render({ count }) {
|
||||
return {
|
||||
message: metric(count),
|
||||
message: count,
|
||||
color: 'blue',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ export default class GithubMilestoneDetail extends GithubAuthV3Service {
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${milestone.title}${label ? ' ' : ''}${label}`,
|
||||
label: `${milestone.title} ${label}`,
|
||||
message: metric(milestoneMetric),
|
||||
color,
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default class GithubMilestone extends GithubAuthV3Service {
|
||||
static render({ user, repo, variant, milestones }) {
|
||||
const milestoneLength = milestones.length
|
||||
let color
|
||||
let qualifier = ''
|
||||
let label = ''
|
||||
|
||||
switch (variant) {
|
||||
case 'all':
|
||||
@@ -51,16 +51,16 @@ export default class GithubMilestone extends GithubAuthV3Service {
|
||||
break
|
||||
case 'open':
|
||||
color = 'red'
|
||||
qualifier = 'active'
|
||||
label = 'active'
|
||||
break
|
||||
case 'closed':
|
||||
color = 'green'
|
||||
qualifier = 'completed'
|
||||
label = 'completed'
|
||||
break
|
||||
}
|
||||
|
||||
return {
|
||||
label: `${qualifier}${qualifier ? ' ' : ''}milestones`,
|
||||
label: `${label} milestones`,
|
||||
message: metric(milestoneLength),
|
||||
color,
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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: [] },
|
||||
})
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -32,8 +32,6 @@ export default class LibrariesIoDependentRepos extends LibrariesIoBase {
|
||||
},
|
||||
]
|
||||
|
||||
static _cacheLength = 900
|
||||
|
||||
static defaultBadgeData = {
|
||||
label: 'dependent repos',
|
||||
}
|
||||
|
||||
@@ -32,8 +32,6 @@ export default class LibrariesIoDependents extends LibrariesIoBase {
|
||||
},
|
||||
]
|
||||
|
||||
static _cacheLength = 900
|
||||
|
||||
static defaultBadgeData = {
|
||||
label: 'dependents',
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import Joi from 'joi'
|
||||
import { nonNegativeInteger } from '../validators.js'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { metric } from '../text-formatters.js'
|
||||
|
||||
// https://developer.opencollective.com/#/api/collectives?id=get-info
|
||||
const collectiveDetailsSchema = Joi.object().keys({
|
||||
@@ -31,11 +30,12 @@ export default class OpencollectiveBase extends BaseJsonService {
|
||||
}
|
||||
|
||||
static render(backersCount, label) {
|
||||
return {
|
||||
label,
|
||||
message: metric(backersCount),
|
||||
const badge = {
|
||||
message: backersCount,
|
||||
color: backersCount > 0 ? 'brightgreen' : 'lightgrey',
|
||||
}
|
||||
if (label) badge.label = label
|
||||
return badge
|
||||
}
|
||||
|
||||
async fetchCollectiveInfo(collective) {
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { colorScale } from '../color-formatters.js'
|
||||
|
||||
const schema = Joi.object({
|
||||
score: Joi.number().min(0).required(),
|
||||
}).required()
|
||||
|
||||
const ossfScorecardColorScale = colorScale(
|
||||
[2, 5, 8, 10],
|
||||
['red', 'yellow', 'yellowgreen', 'green', 'brightgreen']
|
||||
)
|
||||
|
||||
export default class OSSFScorecard extends BaseJsonService {
|
||||
static category = 'analysis'
|
||||
|
||||
static route = { base: 'ossf-scorecard', pattern: ':host/:orgName/:repoName' }
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title: 'OSSF-Scorecard Score',
|
||||
namedParams: {
|
||||
host: 'github.com',
|
||||
orgName: 'rohankh532',
|
||||
repoName: 'org-workflow-add',
|
||||
},
|
||||
staticPreview: this.render({ score: '7.5' }),
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'score' }
|
||||
|
||||
static render({ score }) {
|
||||
return {
|
||||
message: score,
|
||||
color: ossfScorecardColorScale(score),
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ host, orgName, repoName }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `https://api.securityscorecards.dev/projects/${host}/${orgName}/${repoName}`,
|
||||
errorMessages: {
|
||||
404: 'invalid repo path',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ host, orgName, repoName }) {
|
||||
const { score } = await this.fetch({ host, orgName, repoName })
|
||||
|
||||
return this.constructor.render({ score })
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import Joi from 'joi'
|
||||
import { createServiceTester } from '../tester.js'
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('score valid')
|
||||
.get('/github.com/rohankh532/org-workflow-add.json')
|
||||
.expectBadge({
|
||||
label: 'score',
|
||||
message: Joi.number().min(0),
|
||||
color: Joi.string().allow(
|
||||
'red',
|
||||
'yellow',
|
||||
'yellowgreen',
|
||||
'green',
|
||||
'brightgreen'
|
||||
),
|
||||
})
|
||||
|
||||
t.create('score ivalid')
|
||||
.get('/github.com/invalid-user/invalid-repo.json')
|
||||
.expectBadge({
|
||||
label: 'score',
|
||||
message: 'invalid repo path',
|
||||
color: 'red',
|
||||
})
|
||||
@@ -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 = `
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
@@ -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',
|
||||
})
|
||||
@@ -1,53 +0,0 @@
|
||||
import Joi from 'joi'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { metric } from '../text-formatters.js'
|
||||
import { nonNegativeInteger } from '../validators.js'
|
||||
|
||||
const documentation = `<p>A measure of how many developers have liked a package. This provides a raw measure of the overall sentiment of a package from peer developers.</p>`
|
||||
|
||||
const keywords = ['dart', 'flutter']
|
||||
|
||||
const schema = Joi.object({
|
||||
likeCount: nonNegativeInteger,
|
||||
}).required()
|
||||
|
||||
const title = 'Pub Likes'
|
||||
|
||||
export default class PubLikes extends BaseJsonService {
|
||||
static category = 'rating'
|
||||
|
||||
static route = { base: 'pub/likes', pattern: ':packageName' }
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title,
|
||||
keywords,
|
||||
documentation,
|
||||
namedParams: { packageName: 'analysis_options' },
|
||||
staticPreview: this.render({ likeCount: 1000 }),
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'likes' }
|
||||
|
||||
static render({ likeCount }) {
|
||||
return {
|
||||
label: 'likes',
|
||||
message: metric(likeCount),
|
||||
color: 'blue',
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ packageName }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `https://pub.dev/api/packages/${packageName}/score`,
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ packageName }) {
|
||||
const score = await this.fetch({ packageName })
|
||||
const likeCount = score.likeCount
|
||||
return this.constructor.render({ likeCount })
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import { isMetric } from '../test-validators.js'
|
||||
import { createServiceTester } from '../tester.js'
|
||||
|
||||
export const t = await createServiceTester()
|
||||
|
||||
t.create('pub likes (valid)').get('/analysis_options.json').expectBadge({
|
||||
label: 'likes',
|
||||
message: isMetric,
|
||||
color: 'blue',
|
||||
})
|
||||
|
||||
t.create('pub likes (not found)').get('/analysisoptions.json').expectBadge({
|
||||
label: 'likes',
|
||||
message: 'not found',
|
||||
color: 'red',
|
||||
})
|
||||
|
||||
t.create('pub likes (invalid)').get('/analysis-options.json').expectBadge({
|
||||
label: 'likes',
|
||||
message: 'invalid',
|
||||
color: 'lightgrey',
|
||||
})
|
||||
@@ -1,55 +0,0 @@
|
||||
import Joi from 'joi'
|
||||
import { floorCount } from '../color-formatters.js'
|
||||
import { BaseJsonService } from '../index.js'
|
||||
import { nonNegativeInteger } from '../validators.js'
|
||||
|
||||
const documentation = `<p>A measure of quality. This includes several dimensions of quality such as code style, platform support, and maintainability.</p>`
|
||||
|
||||
const keywords = ['dart', 'flutter']
|
||||
|
||||
const schema = Joi.object({
|
||||
grantedPoints: nonNegativeInteger,
|
||||
maxPoints: nonNegativeInteger,
|
||||
}).required()
|
||||
|
||||
const title = 'Pub Points'
|
||||
|
||||
export default class PubPoints extends BaseJsonService {
|
||||
static category = 'rating'
|
||||
|
||||
static route = { base: 'pub/points', pattern: ':packageName' }
|
||||
|
||||
static examples = [
|
||||
{
|
||||
title,
|
||||
keywords,
|
||||
documentation,
|
||||
namedParams: { packageName: 'analysis_options' },
|
||||
staticPreview: this.render({ grantedPoints: 120, maxPoints: 130 }),
|
||||
},
|
||||
]
|
||||
|
||||
static defaultBadgeData = { label: 'points' }
|
||||
|
||||
static render({ grantedPoints, maxPoints }) {
|
||||
return {
|
||||
label: 'points',
|
||||
message: `${grantedPoints}/${maxPoints}`,
|
||||
color: floorCount((grantedPoints / maxPoints) * 100, 40, 60, 80),
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ packageName }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `https://pub.dev/api/packages/${packageName}/score`,
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ packageName }) {
|
||||
const score = await this.fetch({ packageName })
|
||||
const grantedPoints = score.grantedPoints
|
||||
const maxPoints = score.maxPoints
|
||||
return this.constructor.render({ grantedPoints, maxPoints })
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user