Version 2.1
- No plugins are enabled by default - Logs from setup can be hidden - Number of repositories to inspect can be configured (default to 100) - Default events for habits plugin is now 100 - Number of events for habits can be overriden in query - Server app improvments - Test improvements - Better test
This commit is contained in:
86
CONTRIBUTING.md
Normal file
86
CONTRIBUTING.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# 📊 GitHub metrics
|
||||||
|
|
||||||
|
## 💪 Interested in contributing ?
|
||||||
|
|
||||||
|
Nice ! Read the few sections below to understand how this project is structured.
|
||||||
|
|
||||||
|
### 👨💻 General informations
|
||||||
|
|
||||||
|
#### Adding new metrics through GraphQL API, REST API or Third-Party service
|
||||||
|
|
||||||
|
To use [GitHub GraphQL API](https://docs.github.com/en/graphql), update the GraphQL query from `templates/*/query.graphql`.
|
||||||
|
Raw queried data should be exposed in `data.user` whereas computed data should be in `data.computed`, and code should be updated through `templates/*/template.mjs`.
|
||||||
|
|
||||||
|
To use [GitHub Rest API](https://docs.github.com/en/rest) or a third-party service instead, create a new plugin in `src/plugins`.
|
||||||
|
Plugins should be self-sufficient and re-exported from [src/plugins/index.mjs](https://github.com/lowlighter/metrics/blob/master/src/plugins/index.mjs), to be later included in the `//Plugins` section of `templates/*/template.mjs`.
|
||||||
|
Data generated should be exposed in `data.computed.plugins[plugin]` where `plugin` is your plugin's name.
|
||||||
|
|
||||||
|
#### Updating the SVG template
|
||||||
|
|
||||||
|
The SVG template is located in `templates/*/image.svg` and include the CSS from `templates/*/style.css`.
|
||||||
|
|
||||||
|
It is rendered with [EJS](https://github.com/mde/ejs) so you can actually include variables (e.g. `<%= user.name %>`) and execute simple code, like control statements.
|
||||||
|
|
||||||
|
#### Metrics server and GitHub action
|
||||||
|
|
||||||
|
Most of the time, you won't need to edit these, unless you're integrating features directly tied to them.
|
||||||
|
Remember that SVG image is actually generated from `src/metrics.mjs`, independently from metrics server and GitHub action.
|
||||||
|
|
||||||
|
Metrics server code is located in `src/app.mjs` and instantiates an `express` server app, `octokit`s instances, middlewares (like rate-limiter) and routes.
|
||||||
|
|
||||||
|
GitHub action code is located in `action/index.mjs` and instantiates `octokit`s instances and retrieves action parameters.
|
||||||
|
It then use directly `src/metrics.mjs` to generate the SVG image and commit them to user's repository.
|
||||||
|
You must run `npm run build` to rebuild the GitHub action.
|
||||||
|
|
||||||
|
#### Testing new features
|
||||||
|
|
||||||
|
To test new features, setup a metrics server with a test token and `debug` mode enabled.
|
||||||
|
This way you'll be able to rapidly test SVG renders with your browser.
|
||||||
|
|
||||||
|
### 🗂️ Project structure
|
||||||
|
|
||||||
|
#### Metrics generator
|
||||||
|
|
||||||
|
* `src/setup.mjs` contains the configuration setup
|
||||||
|
* `src/metrics.mjs` contains the metrics renderer
|
||||||
|
* `src/templates/*` contains templates files
|
||||||
|
* `src/templates/*/image.svg` contains the template used by the generated SVG image
|
||||||
|
* `src/templates/*/query.graphql` is the GraphQL query sent to GitHub GraphQL API
|
||||||
|
* `src/templates/*/style.css` contains the style used by the generated SVG image
|
||||||
|
* `src/templates/*/template.mjs` contains the code which prepares data for rendering
|
||||||
|
* `src/plugins/*` contains the source code of metrics plugins
|
||||||
|
|
||||||
|
#### Metrics server instance
|
||||||
|
|
||||||
|
* `index.mjs` contains the metrics server entry point
|
||||||
|
* `src/app.mjs` contains the metrics server code which serves, renders, restricts/rate limit, etc.
|
||||||
|
|
||||||
|
#### GitHub action
|
||||||
|
|
||||||
|
* `action.yml` contains the GitHub action descriptor
|
||||||
|
* `action/index.mjs` contains the GitHub action code
|
||||||
|
* `action/dist/index.js` contains compiled the GitHub action code
|
||||||
|
* `utils/build.mjs` contains the GitHub action builder
|
||||||
|
|
||||||
|
### 📦 Used packages
|
||||||
|
|
||||||
|
* [express/express.js](https://github.com/expressjs/express) and [expressjs/compression](https://github.com/expressjs/compression)
|
||||||
|
* To serve, compute and render a GitHub user's metrics
|
||||||
|
* [nfriedly/express-rate-limit](https://github.com/nfriedly/express-rate-limit)
|
||||||
|
* To apply rate limiting on server and avoid spams and hitting GitHub API's own rate limit
|
||||||
|
* [octokit/graphql.js](https://github.com/octokit/graphql.js/) and [octokit/rest.js](https://github.com/octokit/rest.js)
|
||||||
|
* To perform request to GitHub GraphQL API and GitHub REST API
|
||||||
|
* [mde/ejs](https://github.com/mde/ejs)
|
||||||
|
* To render SVG images
|
||||||
|
* [ptarjan/node-cache](https://github.com/ptarjan/node-cache)
|
||||||
|
* To cache generated content
|
||||||
|
* [renanbastos93/image-to-base64](https://github.com/renanbastos93/image-to-base64)
|
||||||
|
* To generate base64 representation of users' avatars
|
||||||
|
* [svg/svgo](https://github.com/svg/svgo)
|
||||||
|
* To optimize generated SVG
|
||||||
|
* [axios/axios](https://github.com/axios/axios)
|
||||||
|
* To make HTTP/S requests
|
||||||
|
* [actions/toolkit](https://github.com/actions/toolkit/tree/master) and [vercel/ncc](https://github.com/vercel/ncc)
|
||||||
|
* To build the GitHub Action
|
||||||
|
* [vuejs/vue](https://github.com/vuejs/vue)
|
||||||
|
* To display server application
|
||||||
102
README.md
102
README.md
@@ -3,13 +3,19 @@
|
|||||||
 
|
 
|
||||||
|
|
||||||
Generates your own GitHub metrics as an SVG image to put them on your profile page or elsewhere !
|
Generates your own GitHub metrics as an SVG image to put them on your profile page or elsewhere !
|
||||||
See what it looks like below :
|
|
||||||
|

|
||||||
|
|
||||||
|
Still not enough data for you ? You can enable additional plugins for even more metrics !
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 🦑 Interested to get your own ?
|
### 🦑 Interested to get your own ?
|
||||||
|
|
||||||
Try it now at [metrics.lecoq.io](https://metrics.lecoq.io/) with your GitHub username !
|
Try it now at [metrics.lecoq.io](https://metrics.lecoq.io/) with your GitHub username !
|
||||||
|
|
||||||
|
For a fully-featured experience, setup this as a [GitHub Action](https://github.com/marketplace/actions/github-metrics-as-svg-image) !
|
||||||
|
|
||||||
## 📜 How to use ?
|
## 📜 How to use ?
|
||||||
|
|
||||||
### ⚙️ Using GitHub Action on your profile repo (~5 min setup)
|
### ⚙️ Using GitHub Action on your profile repo (~5 min setup)
|
||||||
@@ -150,9 +156,10 @@ Since GitHub API has rate limitations, the shared instance has a few limitations
|
|||||||
* Your generated metrics won't be updated during this amount of time
|
* Your generated metrics won't be updated during this amount of time
|
||||||
* If you enable or disable plugins in url parameters, you'll need to wait for cache expiration before these changes are applied
|
* If you enable or disable plugins in url parameters, you'll need to wait for cache expiration before these changes are applied
|
||||||
* The rate limiter is enabled, although it won't affect already cached users metrics
|
* The rate limiter is enabled, although it won't affect already cached users metrics
|
||||||
* Plugins which consume additional requests or require elevated token rights are disabled
|
* Plugins which consume additional requests or require elevated token rights are disabled. The following plugins are available :
|
||||||
* PageSpeed plugin can still be enabled by passing `?pagespeed=1`, but metrics generation can take up some time when it has not been cached yet
|
* PageSpeed plugin can be enabled by passing `?pagespeed=1`, but metrics generation can take up some time when it has not been cached yet
|
||||||
* Languages and Follow-up plugins are enabled by default by can be disabled respectively with `?languages=0` and `?followup=0`
|
* Languages plugin can be enabled by passing `?languages=1`
|
||||||
|
* Follow-up plugin can be enabled by passing `?followup=1`
|
||||||
|
|
||||||
To ensure maximum availability, consider deploying your own instance or use the GitHub Action.
|
To ensure maximum availability, consider deploying your own instance or use the GitHub Action.
|
||||||
|
|
||||||
@@ -267,7 +274,7 @@ Open and edit `settings.json` to configure your instance using a text editor of
|
|||||||
//Enable or disable this plugin. Pass "?habits=1" in url to generate coding habits based on your recent activity
|
//Enable or disable this plugin. Pass "?habits=1" in url to generate coding habits based on your recent activity
|
||||||
"enabled":true,
|
"enabled":true,
|
||||||
//Number of events used to compute coding habits (capped at 100 by GitHub API)
|
//Number of events used to compute coding habits (capped at 100 by GitHub API)
|
||||||
"from":50,
|
"from":100,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -511,8 +518,6 @@ The *follow-up* plugin allows you to compute the ratio of opened/closed issues a
|
|||||||
<details>
|
<details>
|
||||||
<summary>💬 About</summary>
|
<summary>💬 About</summary>
|
||||||
|
|
||||||
This plugin is enabled by default. To disable it, explicitly opt-out.
|
|
||||||
|
|
||||||
##### Setup with GitHub actions
|
##### Setup with GitHub actions
|
||||||
|
|
||||||
Add the following to your workflow :
|
Add the following to your workflow :
|
||||||
@@ -545,8 +550,6 @@ The *languages* plugin allows you to compute which languages you use the most in
|
|||||||
<details>
|
<details>
|
||||||
<summary>💬 About</summary>
|
<summary>💬 About</summary>
|
||||||
|
|
||||||
This plugin is enabled by default. To disable it, explicitly opt-out.
|
|
||||||
|
|
||||||
##### Setup with GitHub actions
|
##### Setup with GitHub actions
|
||||||
|
|
||||||
Add the following to your workflow :
|
Add the following to your workflow :
|
||||||
@@ -591,69 +594,13 @@ Add the following to your workflow :
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### 🗂️ Project structure
|
|
||||||
|
|
||||||
#### Metrics generator
|
|
||||||
|
|
||||||
* `src/setup.mjs` contains the configuration setup
|
|
||||||
* `src/metrics.mjs` contains the metrics renderer
|
|
||||||
* `src/templates/*` contains templates files
|
|
||||||
* `src/templates/*/image.svg` contains the template used by the generated SVG image
|
|
||||||
* `src/templates/*/query.graphql` is the GraphQL query sent to GitHub GraphQL API
|
|
||||||
* `src/templates/*/style.css` contains the style used by the generated SVG image
|
|
||||||
* `src/templates/*/template.mjs` contains the code which prepares data for rendering
|
|
||||||
* `src/plugins/*` contains the source code of metrics plugins
|
|
||||||
|
|
||||||
#### Metrics server instance
|
|
||||||
|
|
||||||
* `index.mjs` contains the metrics server entry point
|
|
||||||
* `src/app.mjs` contains the metrics server code which serves, renders, restricts/rate limit, etc.
|
|
||||||
|
|
||||||
#### GitHub action
|
|
||||||
|
|
||||||
* `action.yml` contains the GitHub action descriptor
|
|
||||||
* `action/index.mjs` contains the GitHub action code
|
|
||||||
* `action/dist/index.js` contains compiled the GitHub action code
|
|
||||||
* `utils/build.mjs` contains the GitHub action builder
|
|
||||||
|
|
||||||
### 💪 Contributing and customizing
|
### 💪 Contributing and customizing
|
||||||
|
|
||||||
If you would like to suggest a new feature, find a bug or need help, you can fill an [issue](https://github.com/lowlighter/metrics/issues) describing your problem.
|
If you would like to suggest a new feature, find a bug or need help, you can fill an [issue](https://github.com/lowlighter/metrics/issues) describing your problem.
|
||||||
|
|
||||||
If you're motivated enough, you can submit a [pull request](https://github.com/lowlighter/metrics/pulls) to integrate new features or to solve open issues.
|
If you're motivated enough, you can submit a [pull request](https://github.com/lowlighter/metrics/pulls) to integrate new features or to solve open issues.
|
||||||
|
|
||||||
Read the few sections below to get started with project structure.
|
Read [contributing.md](https://github.com/lowlighter/metrics/blob/master/CONTRIBUTING.md) for more information about this.
|
||||||
|
|
||||||
#### Adding new metrics through GraphQL API, REST API or Third-Party service
|
|
||||||
|
|
||||||
To use [GitHub GraphQL API](https://docs.github.com/en/graphql), update the GraphQL query from `templates/*/query.graphql`.
|
|
||||||
Raw queried data should be exposed in `data.user` whereas computed data should be in `data.computed`, and code should be updated through `templates/*/template.mjs`.
|
|
||||||
|
|
||||||
To use [GitHub Rest API](https://docs.github.com/en/rest) or a third-party service instead, create a new plugin in `src/plugins`.
|
|
||||||
Plugins should be self-sufficient and re-exported from [src/plugins/index.mjs](https://github.com/lowlighter/metrics/blob/master/src/plugins/index.mjs), to be later included in the `//Plugins` section of `templates/*/template.mjs`.
|
|
||||||
Data generated should be exposed in `data.computed.plugins[plugin]` where `plugin` is your plugin's name.
|
|
||||||
|
|
||||||
#### Updating the SVG template
|
|
||||||
|
|
||||||
The SVG template is located in `templates/*/image.svg` and include the CSS from `templates/*/style.css`.
|
|
||||||
|
|
||||||
It is rendered with [EJS](https://github.com/mde/ejs) so you can actually include variables (e.g. `<%= user.name %>`) and execute simple code, like control statements.
|
|
||||||
|
|
||||||
#### Metrics server and GitHub action
|
|
||||||
|
|
||||||
Most of the time, you won't need to edit these, unless you're integrating features directly tied to them.
|
|
||||||
Remember that SVG image is actually generated from `src/metrics.mjs`, independently from metrics server and GitHub action.
|
|
||||||
|
|
||||||
Metrics server code is located in `src/app.mjs` and instantiates an `express` server app, `octokit`s instances, middlewares (like rate-limiter) and routes.
|
|
||||||
|
|
||||||
GitHub action code is located in `action/index.mjs` and instantiates `octokit`s instances and retrieves action parameters.
|
|
||||||
It then use directly `src/metrics.mjs` to generate the SVG image and commit them to user's repository.
|
|
||||||
You must run `npm run build` to rebuild the GitHub action.
|
|
||||||
|
|
||||||
#### Testing new features
|
|
||||||
|
|
||||||
To test new features, setup a metrics server with a test token and `debug` mode enabled.
|
|
||||||
This way you'll be able to rapidly test SVG renders with your browser.
|
|
||||||
|
|
||||||
### 📖 Useful references
|
### 📖 Useful references
|
||||||
|
|
||||||
@@ -661,29 +608,6 @@ This way you'll be able to rapidly test SVG renders with your browser.
|
|||||||
* [GitHub GraphQL Explorer](https://developer.github.com/v4/explorer/)
|
* [GitHub GraphQL Explorer](https://developer.github.com/v4/explorer/)
|
||||||
* [GitHub Rest API](https://docs.github.com/en/rest)
|
* [GitHub Rest API](https://docs.github.com/en/rest)
|
||||||
|
|
||||||
### 📦 Used packages
|
|
||||||
|
|
||||||
* [express/express.js](https://github.com/expressjs/express) and [expressjs/compression](https://github.com/expressjs/compression)
|
|
||||||
* To serve, compute and render a GitHub user's metrics
|
|
||||||
* [nfriedly/express-rate-limit](https://github.com/nfriedly/express-rate-limit)
|
|
||||||
* To apply rate limiting on server and avoid spams and hitting GitHub API's own rate limit
|
|
||||||
* [octokit/graphql.js](https://github.com/octokit/graphql.js/) and [octokit/rest.js](https://github.com/octokit/rest.js)
|
|
||||||
* To perform request to GitHub GraphQL API and GitHub REST API
|
|
||||||
* [mde/ejs](https://github.com/mde/ejs)
|
|
||||||
* To render SVG images
|
|
||||||
* [ptarjan/node-cache](https://github.com/ptarjan/node-cache)
|
|
||||||
* To cache generated content
|
|
||||||
* [renanbastos93/image-to-base64](https://github.com/renanbastos93/image-to-base64)
|
|
||||||
* To generate base64 representation of users' avatars
|
|
||||||
* [svg/svgo](https://github.com/svg/svgo)
|
|
||||||
* To optimize generated SVG
|
|
||||||
* [axios/axios](https://github.com/axios/axios)
|
|
||||||
* To make HTTP/S requests
|
|
||||||
* [actions/toolkit](https://github.com/actions/toolkit/tree/master) and [vercel/ncc](https://github.com/vercel/ncc)
|
|
||||||
* To build the GitHub Action
|
|
||||||
* [vuejs/vue](https://github.com/vuejs/vue)
|
|
||||||
* To display server application
|
|
||||||
|
|
||||||
All icons were ripped across GitHub's site, but still remains the intellectual property of GitHub.
|
All icons were ripped across GitHub's site, but still remains the intellectual property of GitHub.
|
||||||
See [GitHub Logos and Usage](https://github.com/logos) for more information.
|
See [GitHub Logos and Usage](https://github.com/logos) for more information.
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ inputs:
|
|||||||
default: no
|
default: no
|
||||||
plugin_languages:
|
plugin_languages:
|
||||||
description: Enable most used languages metrics
|
description: Enable most used languages metrics
|
||||||
default: yes
|
default: no
|
||||||
plugin_followup:
|
plugin_followup:
|
||||||
description: Enable owned repositories issues and pull requests metrics
|
description: Enable owned repositories issues and pull requests metrics
|
||||||
default: yes
|
default: no
|
||||||
debug:
|
debug:
|
||||||
description: Enable debug logs
|
description: Enable debug logs
|
||||||
default: no
|
default: no
|
||||||
|
|||||||
2
action/dist/index.js
vendored
2
action/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -28,7 +28,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Load configuration
|
//Load configuration
|
||||||
const conf = await setup()
|
const conf = await setup({log:false})
|
||||||
console.log(`Configuration | loaded`)
|
console.log(`Configuration | loaded`)
|
||||||
|
|
||||||
//Load svg template, style and query
|
//Load svg template, style and query
|
||||||
|
|||||||
78
package-lock.json
generated
78
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "metrics",
|
"name": "metrics",
|
||||||
"version": "1.9.0",
|
"version": "2.1.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -37,9 +37,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/core": {
|
"@octokit/core": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.1.3.tgz",
|
||||||
"integrity": "sha512-AInOFULmwOa7+NFi9F8DlDkm5qtZVmDQayi7TUgChE3yeIGPq0Y+6cAEXPexQ3Ea+uZy66hKEazR7DJyU+4wfw==",
|
"integrity": "sha512-s5UyENGUQBB+ocEOulXq6UH5J16fxuKY2J7ZYrIu9oJYAn0nCwM8hC8o4L23HEzU0SFzNEX86+ffc1T3Vr2ybg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@octokit/auth-token": "^2.4.0",
|
"@octokit/auth-token": "^2.4.0",
|
||||||
"@octokit/graphql": "^4.3.1",
|
"@octokit/graphql": "^4.3.1",
|
||||||
@@ -78,9 +78,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/plugin-request-log": {
|
"@octokit/plugin-request-log": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.1.tgz",
|
||||||
"integrity": "sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw=="
|
"integrity": "sha512-d8vmiGAUGswxErdIGfpd0I2UHo2Cs7EaBDpFUZQ9UqYmA0s5/4XoMO4HBld73xGpCj2BvyVyQe2qd9e+/nvKwQ=="
|
||||||
},
|
},
|
||||||
"@octokit/plugin-rest-endpoint-methods": {
|
"@octokit/plugin-rest-endpoint-methods": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
@@ -136,9 +136,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "14.11.10",
|
"version": "14.14.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.2.tgz",
|
||||||
"integrity": "sha512-yV1nWZPlMFpoXyoknm4S56y2nlTAuFYaJuQtYRAOU7xA/FJ9RY0Xm7QOkaYMMmr8ESdHIuUb6oQgR/0+2NqlyA=="
|
"integrity": "sha512-jeYJU2kl7hL9U5xuI/BhKPZ4vqGM/OmK6whiFAXVhlstzZhVamWhDSmHyGLIp+RVyuF9/d0dqr2P85aFj4BvJg=="
|
||||||
},
|
},
|
||||||
"@types/q": {
|
"@types/q": {
|
||||||
"version": "1.5.4",
|
"version": "1.5.4",
|
||||||
@@ -1421,21 +1421,63 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string.prototype.trimend": {
|
"string.prototype.trimend": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz",
|
||||||
"integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
|
"integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"define-properties": "^1.1.3",
|
"define-properties": "^1.1.3",
|
||||||
"es-abstract": "^1.17.5"
|
"es-abstract": "^1.18.0-next.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"es-abstract": {
|
||||||
|
"version": "1.18.0-next.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
|
||||||
|
"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
|
||||||
|
"requires": {
|
||||||
|
"es-to-primitive": "^1.2.1",
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"has": "^1.0.3",
|
||||||
|
"has-symbols": "^1.0.1",
|
||||||
|
"is-callable": "^1.2.2",
|
||||||
|
"is-negative-zero": "^2.0.0",
|
||||||
|
"is-regex": "^1.1.1",
|
||||||
|
"object-inspect": "^1.8.0",
|
||||||
|
"object-keys": "^1.1.1",
|
||||||
|
"object.assign": "^4.1.1",
|
||||||
|
"string.prototype.trimend": "^1.0.1",
|
||||||
|
"string.prototype.trimstart": "^1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string.prototype.trimstart": {
|
"string.prototype.trimstart": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz",
|
||||||
"integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
|
"integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"define-properties": "^1.1.3",
|
"define-properties": "^1.1.3",
|
||||||
"es-abstract": "^1.17.5"
|
"es-abstract": "^1.18.0-next.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"es-abstract": {
|
||||||
|
"version": "1.18.0-next.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
|
||||||
|
"integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
|
||||||
|
"requires": {
|
||||||
|
"es-to-primitive": "^1.2.1",
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"has": "^1.0.3",
|
||||||
|
"has-symbols": "^1.0.1",
|
||||||
|
"is-callable": "^1.2.2",
|
||||||
|
"is-negative-zero": "^2.0.0",
|
||||||
|
"is-regex": "^1.1.1",
|
||||||
|
"object-inspect": "^1.8.0",
|
||||||
|
"object-keys": "^1.1.1",
|
||||||
|
"object.assign": "^4.1.1",
|
||||||
|
"string.prototype.trimend": "^1.0.1",
|
||||||
|
"string.prototype.trimstart": "^1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
"string_decoder": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "metrics",
|
"name": "metrics",
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"description": "Generate an user's GitHub metrics as SVG image format to embed somewhere else",
|
"description": "Generate an user's GitHub metrics as SVG image format to embed somewhere else",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"port":3000, "//":"Listening port",
|
"port":3000, "//":"Listening port",
|
||||||
"optimize":true, "//":"Optimize SVG image",
|
"optimize":true, "//":"Optimize SVG image",
|
||||||
"debug":false, "//":"Debug mode",
|
"debug":false, "//":"Debug mode",
|
||||||
|
"repositories":100, "//":"Number of repositories to use to compute metrics",
|
||||||
|
|
||||||
"templates":{ "//":"Template configuration",
|
"templates":{ "//":"Template configuration",
|
||||||
"default":"classic", "//":"Default template",
|
"default":"classic", "//":"Default template",
|
||||||
@@ -15,24 +16,24 @@
|
|||||||
|
|
||||||
"plugins":{ "//":"Additional plugins (optional)",
|
"plugins":{ "//":"Additional plugins (optional)",
|
||||||
"pagespeed":{ "//":"Pagespeed plugin",
|
"pagespeed":{ "//":"Pagespeed plugin",
|
||||||
"enabled":false, "//":"Enable or disable PageSpeed metrics",
|
"enabled":true, "//":"Enable or disable PageSpeed metrics",
|
||||||
"token":"******", "//":"Pagespeed token"
|
"token":null, "//":"Pagespeed token"
|
||||||
},
|
},
|
||||||
"traffic":{ "//":"Traffic plugin (GitHub API token must be RW for this to work)",
|
"traffic":{ "//":"Traffic plugin (GitHub API token must be RW for this to work)",
|
||||||
"enabled":true, "//":"Enable or disable repositories total page views is last two weeks"
|
"enabled":false, "//":"Enable or disable repositories total page views is last two weeks"
|
||||||
},
|
},
|
||||||
"lines":{ "//":"Lines plugin",
|
"lines":{ "//":"Lines plugin",
|
||||||
"enabled":true, "//":"Enable or disable repositories total lines added/removed"
|
"enabled":false, "//":"Enable or disable repositories total lines added/removed"
|
||||||
},
|
},
|
||||||
"habits":{ "//":"Habits plugin",
|
"habits":{ "//":"Habits plugin",
|
||||||
"enabled":true, "//":"Enable or disable coding habits metrics",
|
"enabled":false, "//":"Enable or disable coding habits metrics",
|
||||||
"from":50, "//":"Number of activity events to base habits on (up to 100)"
|
"from":100, "//":"Number of activity events to base habits on (up to 100)"
|
||||||
},
|
},
|
||||||
"languages":{ "//":"Languages plugins",
|
"languages":{ "//":"Languages plugins",
|
||||||
"enabled":true, "//":"Enable or disable most used languages metrics (*this plugin is enabled by default)"
|
"enabled":true, "//":"Enable or disable most used languages metrics"
|
||||||
},
|
},
|
||||||
"followup":{ "//":"Follow-up plugin",
|
"followup":{ "//":"Follow-up plugin",
|
||||||
"enabled":true, "//":"Enable owned repositories issues and pull requests metrics (*this plugin is enabled by default)"
|
"enabled":true, "//":"Enable owned repositories issues and pull requests metrics"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
<h1><a href="https://github.com/lowlighter/metrics">Generate your metrics !</a></h1>
|
<h1><a href="https://github.com/lowlighter/metrics">Generate your metrics !</a></h1>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
<div class="step">
|
<div class="step">
|
||||||
<h2>1. Enter your GitHub username</h2>
|
<h2>1. Enter your GitHub username</h2>
|
||||||
<label>
|
<label>
|
||||||
@@ -21,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="step">
|
<div class="step">
|
||||||
<h2>2. Select a template and enable additional plugins</h2>
|
<h2>2. Select a template {{ plugins.list.length ? "and enable additional plugins" : "" }}</h2>
|
||||||
<div class="templates">
|
<div class="templates">
|
||||||
<label v-for="template in templates.list" :key="template">
|
<label v-for="template in templates.list" :key="template">
|
||||||
<input type="radio" v-model="templates.selected" :value="template" @change="load" :disabled="generated.pending">
|
<input type="radio" v-model="templates.selected" :value="template" @change="load" :disabled="generated.pending">
|
||||||
@@ -34,7 +36,7 @@
|
|||||||
{{ plugins.descriptions[plugin] || plugin }}
|
{{ plugins.descriptions[plugin] || plugin }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="cache-notice">
|
<div class="cache-notice" v-if="plugins.list.length">
|
||||||
*To reduce server overhead, metrics are cached. Changes may not be reflected until cache expiration.
|
*To reduce server overhead, metrics are cached. Changes may not be reflected until cache expiration.
|
||||||
</div>
|
</div>
|
||||||
<div class="palette">
|
<div class="palette">
|
||||||
@@ -74,6 +76,8 @@
|
|||||||
For even more features, setup <a href="https://github.com/lowlighter/metrics">lowlighter/metrics</a> as a <a href="https://github.com/marketplace/actions/github-metrics-as-svg-image">GitHub action</a> !
|
For even more features, setup <a href="https://github.com/lowlighter/metrics">lowlighter/metrics</a> as a <a href="https://github.com/marketplace/actions/github-metrics-as-svg-image">GitHub action</a> !
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="/axios.min.js"></script>
|
<script src="/axios.min.js"></script>
|
||||||
@@ -91,7 +95,7 @@
|
|||||||
palette:"light",
|
palette:"light",
|
||||||
plugins:{
|
plugins:{
|
||||||
list:(await axios.get("/plugins.list")).data,
|
list:(await axios.get("/plugins.list")).data,
|
||||||
enabled:{languages:true, followup:true},
|
enabled:{},
|
||||||
descriptions:{
|
descriptions:{
|
||||||
pagespeed:"Website performances",
|
pagespeed:"Website performances",
|
||||||
languages:"Most used languages",
|
languages:"Most used languages",
|
||||||
@@ -122,7 +126,7 @@
|
|||||||
},
|
},
|
||||||
url() {
|
url() {
|
||||||
const plugins = Object.entries(this.plugins.enabled)
|
const plugins = Object.entries(this.plugins.enabled)
|
||||||
.filter(([key, value]) => /^(?:languages|followup)$/.test(key) ? !value : value)
|
.filter(([key, value]) => value)
|
||||||
.map(([key, value]) => `${key}=${+value}`)
|
.map(([key, value]) => `${key}=${+value}`)
|
||||||
.join("&")
|
.join("&")
|
||||||
return `${window.location.href}${this.user}${plugins.length ? `?${plugins}` : ""}`
|
return `${window.location.href}${this.user}${plugins.length ? `?${plugins}` : ""}`
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
console.debug(`metrics/compute/${login} > start`)
|
console.debug(`metrics/compute/${login} > start`)
|
||||||
console.debug(JSON.stringify(q))
|
console.debug(JSON.stringify(q))
|
||||||
const template = q.template || conf.settings.templates.default
|
const template = q.template || conf.settings.templates.default
|
||||||
|
const repositories = Math.max(0, Number(q.repositories)) || conf.settings.repositories || 100
|
||||||
const pending = []
|
const pending = []
|
||||||
const s = (value, end = "") => value > 1 ? {y:"ies", "":"s"}[end] : end
|
const s = (value, end = "") => value > 1 ? {y:"ies", "":"s"}[end] : end
|
||||||
if ((!(template in Templates))||(!(template in conf.templates))||((conf.settings.templates.enabled.length)&&(!conf.settings.templates.enabled.includes(template))))
|
if ((!(template in Templates))||(!(template in conf.templates))||((conf.settings.templates.enabled.length)&&(!conf.settings.templates.enabled.includes(template))))
|
||||||
@@ -24,6 +25,7 @@
|
|||||||
console.debug(`metrics/compute/${login} > query`)
|
console.debug(`metrics/compute/${login} > query`)
|
||||||
const data = await graphql(query
|
const data = await graphql(query
|
||||||
.replace(/[$]login/, `"${login}"`)
|
.replace(/[$]login/, `"${login}"`)
|
||||||
|
.replace(/[$]repositories/, `${repositories}`)
|
||||||
.replace(/[$]calendar.to/, `"${(new Date()).toISOString()}"`)
|
.replace(/[$]calendar.to/, `"${(new Date()).toISOString()}"`)
|
||||||
.replace(/[$]calendar.from/, `"${(new Date(Date.now()-14*24*60*60*1000)).toISOString()}"`)
|
.replace(/[$]calendar.from/, `"${(new Date(Date.now()-14*24*60*60*1000)).toISOString()}"`)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//Setup
|
//Setup
|
||||||
export default function ({login, data, computed, pending, q}, {enabled = true} = {}) {
|
export default function ({login, data, computed, pending, q}, {enabled = false} = {}) {
|
||||||
//Check if plugin is enabled and requirements are met
|
//Check if plugin is enabled and requirements are met
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
return computed.plugins.followup = null
|
return computed.plugins.followup = null
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//Setup
|
//Setup
|
||||||
export default function ({login, rest, computed, pending, q}, {enabled = false, from = 50} = {}) {
|
export default function ({login, rest, computed, pending, q}, {enabled = false, from = 100} = {}) {
|
||||||
//Check if plugin is enabled and requirements are met
|
//Check if plugin is enabled and requirements are met
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
return computed.plugins.habits = null
|
return computed.plugins.habits = null
|
||||||
@@ -8,6 +8,12 @@
|
|||||||
console.debug(`metrics/compute/${login}/plugins > habits`)
|
console.debug(`metrics/compute/${login}/plugins > habits`)
|
||||||
computed.svg.height += 70
|
computed.svg.height += 70
|
||||||
|
|
||||||
|
//Parameter override
|
||||||
|
if (typeof q["habits.from"] === "number") {
|
||||||
|
from = Math.max(0, Math.min(from, q["habits.from"]))
|
||||||
|
console.debug(`metrics/compute/${login}/plugins > habits > events = ${from}`)
|
||||||
|
}
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async solve => {
|
pending.push(new Promise(async solve => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//Setup
|
//Setup
|
||||||
export default function ({login, data, computed, pending, q}, {enabled = true} = {}) {
|
export default function ({login, data, computed, pending, q}, {enabled = false} = {}) {
|
||||||
//Check if plugin is enabled and requirements are met
|
//Check if plugin is enabled and requirements are met
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
return computed.plugins.languages = null
|
return computed.plugins.languages = null
|
||||||
|
|||||||
@@ -3,10 +3,11 @@
|
|||||||
import path from "path"
|
import path from "path"
|
||||||
|
|
||||||
/** Setup */
|
/** Setup */
|
||||||
export default async function () {
|
export default async function ({log = true} = {}) {
|
||||||
|
|
||||||
//Init
|
//Init
|
||||||
console.debug(`metrics/setup > setup`)
|
const logger = log ? console.debug : () => null
|
||||||
|
logger(`metrics/setup > setup`)
|
||||||
const templates = "src/templates"
|
const templates = "src/templates"
|
||||||
const conf = {
|
const conf = {
|
||||||
templates:{},
|
templates:{},
|
||||||
@@ -16,17 +17,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Load settings
|
//Load settings
|
||||||
console.debug(`metrics/setup > load settings.json`)
|
logger(`metrics/setup > load settings.json`)
|
||||||
if (fs.existsSync(path.resolve("settings.json"))) {
|
if (fs.existsSync(path.resolve("settings.json"))) {
|
||||||
conf.settings = JSON.parse(`${await fs.promises.readFile(path.resolve("settings.json"))}`)
|
conf.settings = JSON.parse(`${await fs.promises.readFile(path.resolve("settings.json"))}`)
|
||||||
console.debug(`metrics/setup > load settings.json > success`)
|
logger(`metrics/setup > load settings.json > success`)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
console.debug(`metrics/setup > load settings.json > (missing)`)
|
logger(`metrics/setup > load settings.json > (missing)`)
|
||||||
if (!conf.settings.templates)
|
if (!conf.settings.templates)
|
||||||
conf.settings.templates = {default:"classic", enabled:[]}
|
conf.settings.templates = {default:"classic", enabled:[]}
|
||||||
|
if (!conf.settings.plugins)
|
||||||
|
conf.settings.plugins = {}
|
||||||
if (conf.settings.debug)
|
if (conf.settings.debug)
|
||||||
console.debug(conf.settings)
|
logger(conf.settings)
|
||||||
|
|
||||||
//Load templates
|
//Load templates
|
||||||
if (fs.existsSync(path.resolve(templates))) {
|
if (fs.existsSync(path.resolve(templates))) {
|
||||||
@@ -34,7 +37,7 @@
|
|||||||
//Cache templates
|
//Cache templates
|
||||||
if (/^index.mjs$/.test(name))
|
if (/^index.mjs$/.test(name))
|
||||||
continue
|
continue
|
||||||
console.debug(`metrics/setup > load template [${name}]`)
|
logger(`metrics/setup > load template [${name}]`)
|
||||||
const files = [
|
const files = [
|
||||||
`${templates}/${name}/query.graphql`,
|
`${templates}/${name}/query.graphql`,
|
||||||
`${templates}/${name}/image.svg`,
|
`${templates}/${name}/image.svg`,
|
||||||
@@ -43,14 +46,14 @@
|
|||||||
]
|
]
|
||||||
const [query, image, placeholder, style] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
|
const [query, image, placeholder, style] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
|
||||||
conf.templates[name] = {query, image, placeholder, style}
|
conf.templates[name] = {query, image, placeholder, style}
|
||||||
console.debug(`metrics/setup > load template [${name}] > success`)
|
logger(`metrics/setup > load template [${name}] > success`)
|
||||||
//Debug
|
//Debug
|
||||||
if (conf.settings.debug) {
|
if (conf.settings.debug) {
|
||||||
Object.defineProperty(conf.templates, name, {
|
Object.defineProperty(conf.templates, name, {
|
||||||
get() {
|
get() {
|
||||||
console.debug(`metrics/setup > reload template [${name}]`)
|
logger(`metrics/setup > reload template [${name}]`)
|
||||||
const [query, image, placeholder, style] = files.map(file => `${fs.readFileSync(path.resolve(file))}`)
|
const [query, image, placeholder, style] = files.map(file => `${fs.readFileSync(path.resolve(file))}`)
|
||||||
console.debug(`metrics/setup > reload template [${name}] > success`)
|
logger(`metrics/setup > reload template [${name}] > success`)
|
||||||
return {query, image, placeholder, style}
|
return {query, image, placeholder, style}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -58,12 +61,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.debug(`metrics/setup > load templates from build`)
|
logger(`metrics/setup > load templates from build`)
|
||||||
conf.templates = JSON.parse(Buffer.from(`<#assets>`, "base64").toString("utf8"))
|
conf.templates = JSON.parse(Buffer.from(`<#assets>`, "base64").toString("utf8"))
|
||||||
}
|
}
|
||||||
|
|
||||||
//Conf
|
//Conf
|
||||||
console.debug(`metrics/setup > setup > success`)
|
logger(`metrics/setup > setup > success`)
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ query Metrics {
|
|||||||
gists {
|
gists {
|
||||||
totalCount
|
totalCount
|
||||||
}
|
}
|
||||||
repositories(last: 100, isFork: false, ownerAffiliations: OWNER) {
|
repositories(last: $repositories, isFork: false, ownerAffiliations: OWNER) {
|
||||||
totalCount
|
totalCount
|
||||||
nodes {
|
nodes {
|
||||||
name
|
name
|
||||||
|
|||||||
@@ -20,22 +20,65 @@
|
|||||||
const graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}})
|
const graphql = octokit.graphql.defaults({headers:{authorization: `token ${token}`}})
|
||||||
const rest = new OctokitRest.Octokit({auth:token})
|
const rest = new OctokitRest.Octokit({auth:token})
|
||||||
|
|
||||||
|
//Perform tests
|
||||||
|
await test.build()
|
||||||
|
for (const template of [
|
||||||
|
"classic"
|
||||||
|
]) {
|
||||||
|
for (const q of [
|
||||||
|
{},
|
||||||
|
{followup:1},
|
||||||
|
{languages:1},
|
||||||
|
{followup:1, languages:1},
|
||||||
|
{habits:1, "habits.events":1},
|
||||||
|
{lines:1},
|
||||||
|
{traffic:1},
|
||||||
|
{selfskip:1},
|
||||||
|
{pagespeed:1},
|
||||||
|
{followup:1, languages:1, habits:1, "habits.events":1, lines:1, traffic:1, selfskip:1, pagespeed:1}
|
||||||
|
]) {
|
||||||
|
await test.metrics({graphql, rest, q:{template, repositories:1, ...q}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Metrics tests */
|
||||||
|
test.metrics = async function ({graphql, rest, q}) {
|
||||||
|
//Preparation
|
||||||
|
console.log(`### Checking metrics with plugins [${Object.keys(q).filter(key => /^\w+$/.test(key)).join(", ")}]`)
|
||||||
|
const plugins = {
|
||||||
|
lines:{enabled:true},
|
||||||
|
traffic:{enabled:true},
|
||||||
|
pagespeed:{enabled:true},
|
||||||
|
habits:{enabled:true},
|
||||||
|
selfskip:{enabled:true},
|
||||||
|
languages:{enabled:true},
|
||||||
|
followup:{enabled:true},
|
||||||
|
}
|
||||||
|
|
||||||
//Compute render
|
//Compute render
|
||||||
const conf = await setup()
|
console.log("#### Checking that SVG can be generated")
|
||||||
const rendered = await metrics({login:"lowlighter", q:{}}, {graphql, rest, plugins:{}, conf})
|
const conf = await setup({log:false})
|
||||||
|
const rendered = await metrics({login:"lowlighter", q}, {graphql, rest, plugins, conf})
|
||||||
|
|
||||||
//Ensure it's a well-formed SVG image
|
//Ensure it's a well-formed SVG image
|
||||||
|
console.log("#### Checking that generated SVG can be parsed")
|
||||||
const parsed = libxmljs.parseXml(rendered)
|
const parsed = libxmljs.parseXml(rendered)
|
||||||
if (parsed.errors.length)
|
if (parsed.errors.length)
|
||||||
throw new Error(`Malformed SVG : \n${parsed.errors.join("\n")}`)
|
throw new Error(`Malformed SVG : \n${parsed.errors.join("\n")}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Build test */
|
||||||
|
test.build = async function () {
|
||||||
//Ensure that action has been rebuild
|
//Ensure that action has been rebuild
|
||||||
|
console.log("### Checking that code has been rebuild")
|
||||||
const action = `${await fs.promises.readFile(`${__dirname}/dist/index.js`)}`
|
const action = `${await fs.promises.readFile(`${__dirname}/dist/index.js`)}`
|
||||||
const code = await build()
|
const code = await build()
|
||||||
if (action !== code)
|
if (action !== code)
|
||||||
throw new Error(`GitHub Action has not been rebuild. Run "npm run build" to solve this issue`)
|
throw new Error(`GitHub Action has not been rebuild. Run "npm run build" to solve this issue`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Main
|
//Main
|
||||||
if (/metrics.mjs/.test(process.argv[1])) {
|
if (/metrics.mjs/.test(process.argv[1])) {
|
||||||
//Test
|
//Test
|
||||||
|
|||||||
Reference in New Issue
Block a user