docs(plugins/community): finish writing (closes #778)

This commit is contained in:
lowlighter
2022-01-18 19:56:56 -05:00
parent 62d278c68a
commit 0c70a25288
2 changed files with 282 additions and 52 deletions

View File

@@ -35,7 +35,7 @@ Please respect the following guidelines:
- A plugin should be independant and should not rely on other plugins
- [🧱 core](/source/plugins/core/README.md) and [🗃️ base](/source/plugins/base/README.md) output can be reused though
- A plugin should never edit its original arguments, as the object is shared amongst other plugins and would create unattended side effects
- A plugin should never edit its original arguments, as it is shared amongst other plugins and would create unattended side effects
- Use `imports.metadata.plugins.{plugin-name}.inputs()` to automatically typecheck and default user inputs through defined `metadata.yml`
- Plugin options should respect the "lexical field" of existing option to keep consistency
- Plugin errors should be handled gracefully by partials with error message
@@ -46,6 +46,8 @@ Please respect the following guidelines:
- Pass `{prefixed: true}` to wrap automatically command with [WSL](https://docs.microsoft.com/windows/wsl/about) on Windows
- It is required to work on Linux Ubuntu (as the GitHub action run on it)
> 💡 While the following guide intend to explain the creation process of new plugin, it may also be a good idea to see what existing plugins looks like and see if you want to embark on the adventure!
### 💬 Quick-start
To create a new plugin, clone and setup this repository first:
@@ -82,6 +84,8 @@ category: community
description: Short description
examples:
default: https://via.placeholder.com/468x60?text=No%20preview%20available
authors:
- octocat
supports:
- user
- organization
@@ -101,6 +105,8 @@ inputs:
`name`, `description`, `scopes`, `examples` are used to auto-generate documentation in the `README.md`. For community plugins, `examples` should be set with auto-generated examples of your own profile.
`authors` should contain your GitHub username
`category` should be set to `community`.
Because of GitHub Actions original limitations, only strings, numbers and boolean were actually supported by `action.yml`. *metrics* implemented its own `inputs` validator to circumvent this. It should be pretty simple to use.
@@ -192,7 +198,54 @@ console.assert(limit === true)
### 💬 Filling `index.mjs`
> 🚧 Will be available at a later date
Plugins use [JavaScript modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules).
The default exported module of `index.mjs` will be auto-loaded when *metrics* start.
Below is a breakdown of basic `index.mjs` content
```js
export default async function(
//Shared inputs
{
login, //GitHub username
q, //Raw user inputs (dot notation without plugin_ prefix, don't use it directly)
imports, //Various utilitaires (axios, puppeteer, fs, etc., see /source/app/metrics/utils.mjs)
data, //Raw data from core/base plugin
computed, //Computed data from core/base plugin
rest, //Rest authenticated GitHub octokit
graphql, //Graph QL authenticated GitHub octokit
queries, //Autoloaded queries from ./queries
account, //Account type ("user" or "organization")
},
//Settings and tokens
{
enabled = false
} = {}) {
//Plugin execution
try {
//Check if plugin is enabled and requirements are met
if ((!enabled)||(!q.my_plugin))
return null
//Automatically validate user inputs
//An error will be thrown if `account` type is not supported
//Inputs will have correct typing from `metadata.yml` and unset or invalid options will be set to default
let {option} = imports.metadata.plugins.my_plugin.inputs({data, account, q})
//Automatically template query from /source/plugins/myplugin/queries/myquery.graph ql
const {[account]:stuff} = await graphql(queries.myplugin.myquery({login, account, option}))
//Results
return {stuff}
}
//Handle errors
catch (error) {
throw {error:{message:"An error occured", instance:error}}
}
}
```
> ⚠️ Remember, a plugin should never edit its original arguments, as it is shared amongst other plugins and would create unattended side effects
### 💬 Creating partials
@@ -215,6 +268,40 @@ Partials should have the match the same name as plugin handles, as they're used
[EJS](https://github.com/mde/ejs) framework is used to template content through templating tags (`<% %>`).
### 💬 Filling `README.md`
`README.md` is used as documentation.
Most of it will is auto-generated by `metadata.yml` and `examples.yml` content, so usually it is not required to manually edit it.
The default content looks like below:
```markdown
<ǃ--header-->
<ǃ--/header-->
## ➡️ Available options
<ǃ--options-->
<ǃ--/options-->
## Examples workflows
<ǃ--examples-->
<ǃ--/examples-->
```
- `<ǃ--header-->` will be replaced by an auto-generated header containing plugin name, supported features and output examples based on `metadata.yml`
- `<ǃ--options-->` will be replaced by an auto-generated table containing all referenced option from `metadata.yml`
- `<ǃ--examples-->` will be replaced by workflows from `examples.yml`
> ⚠️ Do not replace these auto-generated placeholder yet! They will be built by the ci workflow and will help making your pull request easier to read
When a plugin requires a token, please add a `## 🗝️ Obtaining a {service} token` section after the available options section.
Complex features may also be documented in additional sections after available options section options if required.
Try to respect current format of `README.md` from other plugins and use a neutral and impersonal writing style if possible.
### 💬 Filling `examples.yml`
Workflow examples from `examples.yml` are used as unit testing and to auto-generate documentation in the `README.md`.
@@ -244,34 +331,62 @@ It uses the same syntax as GitHub action and looks like below:
`prod` should keep `skip: true` as you should use your own render outputs as examples.
### 💬 Filling `README.md`
### 💬 Testing locally and creating mocked data
`README.md` is used as documentation.
The easiest way to test a new plugin is to setup a web instance locally ([see documentation](.github/readme/partials/documentation/setup/local.md)).
Most of it will is auto-generated by `metadata.yml` and `examples.yml` content, so usually it is not required to manually edit it.
The default content looks like below:
```markdown
<ǃ--header-->
<ǃ--/header-->
## ➡️ Available options
<ǃ--options-->
<ǃ--/options-->
## Examples workflows
<ǃ--examples-->
<ǃ--/examples-->
Once server is started, open a browser and try to generate an output with your new plugin enabled and check if it works as expected:
```
http://localhost:3000/username?base=0&my-plugin=1
```
- `<ǃ--header-->` will be replaced by an auto-generated header containing plugin name, supported features and output examples based on `metadata.yml`
- `<ǃ--options-->` will be replaced by an auto-generated table containing all referenced option from `metadata.yml`
- `<ǃ--examples-->` will be replaced by workflows from `examples.yml`
> 💡 You may need to configure your server first by editing `settings.json`. Ensure that:
> - `token` is correctly set when working with GitHub APIs
> - `plugins.default` is set to `true` as plugins are disabled by default
> - or enable your plugins by manually in `plugins`.`my-plugin`.`enabled`
> - `debug` is set to `true` for more verbose output
When a plugin requires a token, please add a `## 🗝️ Obtaining a {service} token` section after the available options section.
When your plugin is finalized, you may need to create mocked data if it either uses GitHub APIs or any external service.
Complex features may also be documented in additional sections after available options section options if required.
They must be created in `tests/mocks/api`:
- use `github` directory for all related GitHub APIs data
- use `axios` directory for all external service that you call using `imports.axios`
> 💡 Files from these directories are auto-loaded, so it is just required to create them with faked data.
Finally [/source/app/web/statics/app.placeholder.js](/source/app/web/statics/app.placeholder.js) to add mocked placeholder data to make users using the shared instance able to preview a render locally without any server computation.
### 💬 Submitting a pull request
If you made it until there, congratulations 🥳!
You're almost done, review the following checklist before submitting a pull request:
- [x] I have correctly filled `metadata.yml`
- [x] `name` is set with an unused emoji and plugin name
- [x] `category` is set to `community`
- [x] `examples` contains links towards a rendered output hosted by you
- [x] `authors` contains my GitHub username
- [x] `supports` list which account type are supported
- [x] `scopes` are correctly listed with their associated names on GitHub (leave an empty array if not applicable)
- [x] `inputs` are correctly filled
- [x] I have implemented my plugin
- [x] `index.mjs` respects the plugins guidelines
- [x] I have tested my plugin locally
- [x] `tests/mocks` ... have been created
- [x] `app.placeholder.js` has been updated for preview from web instances
- [x] `examples.yml` contains workflows examples (at least one is required)
- [x] `skip: true` has been set for `prod` attribute in each test
- [x] `npm run linter` yields no errors
- [x] I have documented my plugin
- [x] `README.md` eventually describes complex setup or options (if applicable)
- [x] I am ready!
- [x] Checkout any generated files (in fact, don't run `npm run build`)
- [x] Commit and push your changes (commits are squashed, no need to rebase)
- [x] Open a new [pull request](https://github.com/lowlighter/metrics/pulls)
- [x] Post a screenshot or a render in the pull request so it can be previewed
> 💡 A pull request **will need** to have passing builds and an example screenshot if you want to get it merged.
> Maintainers may request changes in some cases
> 🎊 Thanks a lot for your contribution!
Try to respect current format of `README.md` from other plugins and use a neutral and impersonal writing style if possible.

View File

@@ -44,7 +44,7 @@ Please respect the following guidelines:
- A plugin should be independant and should not rely on other plugins
- [🧱 core](/source/plugins/core/README.md) and [🗃️ base](/source/plugins/base/README.md) output can be reused though
- A plugin should never edit its original arguments, as the object is shared amongst other plugins and would create unattended side effects
- A plugin should never edit its original arguments, as it is shared amongst other plugins and would create unattended side effects
- Use `imports.metadata.plugins.{plugin-name}.inputs()` to automatically typecheck and default user inputs through defined `metadata.yml`
- Plugin options should respect the "lexical field" of existing option to keep consistency
- Plugin errors should be handled gracefully by partials with error message
@@ -55,6 +55,8 @@ Please respect the following guidelines:
- Pass `{prefixed: true}` to wrap automatically command with [WSL](https://docs.microsoft.com/windows/wsl/about) on Windows
- It is required to work on Linux Ubuntu (as the GitHub action run on it)
> 💡 While the following guide intend to explain the creation process of new plugin, it may also be a good idea to see what existing plugins looks like and see if you want to embark on the adventure!
### 💬 Quick-start
To create a new plugin, clone and setup this repository first:
@@ -91,6 +93,8 @@ category: community
description: Short description
examples:
default: https://via.placeholder.com/468x60?text=No%20preview%20available
authors:
- octocat
supports:
- user
- organization
@@ -110,6 +114,8 @@ inputs:
`name`, `description`, `scopes`, `examples` are used to auto-generate documentation in the `README.md`. For community plugins, `examples` should be set with auto-generated examples of your own profile.
`authors` should contain your GitHub username
`category` should be set to `community`.
Because of GitHub Actions original limitations, only strings, numbers and boolean were actually supported by `action.yml`. *metrics* implemented its own `inputs` validator to circumvent this. It should be pretty simple to use.
@@ -201,7 +207,54 @@ console.assert(limit === true)
### 💬 Filling `index.mjs`
> 🚧 Will be available at a later date
Plugins use [JavaScript modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules).
The default exported module of `index.mjs` will be auto-loaded when *metrics* start.
Below is a breakdown of basic `index.mjs` content
```js
export default async function(
//Shared inputs
{
login, //GitHub username
q, //Raw user inputs (dot notation without plugin_ prefix, don't use it directly)
imports, //Various utilitaires (axios, puppeteer, fs, etc., see /source/app/metrics/utils.mjs)
data, //Raw data from core/base plugin
computed, //Computed data from core/base plugin
rest, //Rest authenticated GitHub octokit
graphql, //Graph QL authenticated GitHub octokit
queries, //Autoloaded queries from ./queries
account, //Account type ("user" or "organization")
},
//Settings and tokens
{
enabled = false
} = {}) {
//Plugin execution
try {
//Check if plugin is enabled and requirements are met
if ((!enabled)||(!q.my_plugin))
return null
//Automatically validate user inputs
//An error will be thrown if `account` type is not supported
//Inputs will have correct typing from `metadata.yml` and unset or invalid options will be set to default
let {option} = imports.metadata.plugins.my_plugin.inputs({data, account, q})
//Automatically template query from /source/plugins/myplugin/queries/myquery.graph ql
const {[account]:stuff} = await graphql(queries.myplugin.myquery({login, account, option}))
//Results
return {stuff}
}
//Handle errors
catch (error) {
throw {error:{message:"An error occured", instance:error}}
}
}
```
> ⚠️ Remember, a plugin should never edit its original arguments, as it is shared amongst other plugins and would create unattended side effects
### 💬 Creating partials
@@ -224,6 +277,40 @@ Partials should have the match the same name as plugin handles, as they're used
[EJS](https://github.com/mde/ejs) framework is used to template content through templating tags (``).
### 💬 Filling `README.md`
`README.md` is used as documentation.
Most of it will is auto-generated by `metadata.yml` and `examples.yml` content, so usually it is not required to manually edit it.
The default content looks like below:
```markdown
<ǃ--header-->
<ǃ--/header-->
## ➡️ Available options
<ǃ--options-->
<ǃ--/options-->
## Examples workflows
<ǃ--examples-->
<ǃ--/examples-->
```
- `<ǃ--header-->` will be replaced by an auto-generated header containing plugin name, supported features and output examples based on `metadata.yml`
- `<ǃ--options-->` will be replaced by an auto-generated table containing all referenced option from `metadata.yml`
- `<ǃ--examples-->` will be replaced by workflows from `examples.yml`
> ⚠️ Do not replace these auto-generated placeholder yet! They will be built by the ci workflow and will help making your pull request easier to read
When a plugin requires a token, please add a `## 🗝️ Obtaining a {service} token` section after the available options section.
Complex features may also be documented in additional sections after available options section options if required.
Try to respect current format of `README.md` from other plugins and use a neutral and impersonal writing style if possible.
### 💬 Filling `examples.yml`
Workflow examples from `examples.yml` are used as unit testing and to auto-generate documentation in the `README.md`.
@@ -253,34 +340,62 @@ It uses the same syntax as GitHub action and looks like below:
`prod` should keep `skip: true` as you should use your own render outputs as examples.
### 💬 Filling `README.md`
### 💬 Testing locally and creating mocked data
`README.md` is used as documentation.
The easiest way to test a new plugin is to setup a web instance locally ([see documentation](.github/readme/partials/documentation/setup/local.md)).
Most of it will is auto-generated by `metadata.yml` and `examples.yml` content, so usually it is not required to manually edit it.
The default content looks like below:
```markdown
<ǃ--header-->
<ǃ--/header-->
## ➡️ Available options
<ǃ--options-->
<ǃ--/options-->
## Examples workflows
<ǃ--examples-->
<ǃ--/examples-->
Once server is started, open a browser and try to generate an output with your new plugin enabled and check if it works as expected:
```
http://localhost:3000/username?base=0&my-plugin=1
```
- `<ǃ--header-->` will be replaced by an auto-generated header containing plugin name, supported features and output examples based on `metadata.yml`
- `<ǃ--options-->` will be replaced by an auto-generated table containing all referenced option from `metadata.yml`
- `<ǃ--examples-->` will be replaced by workflows from `examples.yml`
> 💡 You may need to configure your server first by editing `settings.json`. Ensure that:
> - `token` is correctly set when working with GitHub APIs
> - `plugins.default` is set to `true` as plugins are disabled by default
> - or enable your plugins by manually in `plugins`.`my-plugin`.`enabled`
> - `debug` is set to `true` for more verbose output
When a plugin requires a token, please add a `## 🗝️ Obtaining a {service} token` section after the available options section.
When your plugin is finalized, you may need to create mocked data if it either uses GitHub APIs or any external service.
Complex features may also be documented in additional sections after available options section options if required.
They must be created in `tests/mocks/api`:
- use `github` directory for all related GitHub APIs data
- use `axios` directory for all external service that you call using `imports.axios`
> 💡 Files from these directories are auto-loaded, so it is just required to create them with faked data.
Finally [/source/app/web/statics/app.placeholder.js](/source/app/web/statics/app.placeholder.js) to add mocked placeholder data to make users using the shared instance able to preview a render locally without any server computation.
### 💬 Submitting a pull request
If you made it until there, congratulations 🥳!
You're almost done, review the following checklist before submitting a pull request:
- [x] I have correctly filled `metadata.yml`
- [x] `name` is set with an unused emoji and plugin name
- [x] `category` is set to `community`
- [x] `examples` contains links towards a rendered output hosted by you
- [x] `authors` contains my GitHub username
- [x] `supports` list which account type are supported
- [x] `scopes` are correctly listed with their associated names on GitHub (leave an empty array if not applicable)
- [x] `inputs` are correctly filled
- [x] I have implemented my plugin
- [x] `index.mjs` respects the plugins guidelines
- [x] I have tested my plugin locally
- [x] `tests/mocks` ... have been created
- [x] `app.placeholder.js` has been updated for preview from web instances
- [x] `examples.yml` contains workflows examples (at least one is required)
- [x] `skip: true` has been set for `prod` attribute in each test
- [x] `npm run linter` yields no errors
- [x] I have documented my plugin
- [x] `README.md` eventually describes complex setup or options (if applicable)
- [x] I am ready!
- [x] Checkout any generated files (in fact, don't run `npm run build`)
- [x] Commit and push your changes (commits are squashed, no need to rebase)
- [x] Open a new [pull request](https://github.com/lowlighter/metrics/pulls)
- [x] Post a screenshot or a render in the pull request so it can be previewed
> 💡 A pull request **will need** to have passing builds and an example screenshot if you want to get it merged.
> Maintainers may request changes in some cases
> 🎊 Thanks a lot for your contribution!
Try to respect current format of `README.md` from other plugins and use a neutral and impersonal writing style if possible.