Skip to content

Commit dd2d46b

Browse files
authored
Merge pull request #563 from linear-b/split-plugins-for-dev
split pages to usage and dev
2 parents d7fc54b + 94fff64 commit dd2d46b

File tree

3 files changed

+174
-170
lines changed

3 files changed

+174
-170
lines changed

docs/plugins-for-developers.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Plugins Development
2+
3+
## Create Filter Function Plugins
4+
5+
gitStream plugins are based on the [CommonJS](https://en.wikipedia.org/wiki/CommonJS) module standard, a widely used pattern for structuring and importing JavaScript modules.
6+
7+
!!! info "Supported JavaScript Dependencies"
8+
gitStream supports the following JavaScript dependencies: [axios](https://github.com/axios/axios), github actions core (@actions/core), [moment](https://github.com/moment/moment), [lodash](https://github.com/lodash/lodash), octokit rest api (@octokit/rest)
9+
10+
No other dependencies are supported at this time. If you have recommendations for new dependencies, please open a new issue on the [gitStream GitHub repo](https://github.com/linear-b/gitstream).
11+
12+
### Define a New Plugin
13+
14+
Each filter function plugin must have its own unique directory inside the appropriate `/filters` directory for your repo or organization. To create a new filter function, create an index.js file inside the plugin's top-level directory, all plugins must have an index.js file that serves as the primary entry point
15+
16+
One of the functions contained inside this file must be exported via `module.exports`, using the following conventions:
17+
18+
Export plugins that use synchronous code:
19+
20+
``` javascript
21+
function myFilter(author) {
22+
return "Hello ${author}!";
23+
};
24+
25+
module.exports = myFilter;
26+
```
27+
28+
### Define a New Asynchronous Plugin (async)
29+
30+
When using async JavaScript in your plugin, you need two things:
31+
32+
* A primary async function that returns a `callback()` containing any errors as the first argument and the result of the filter as the second.
33+
* A `module.exports` statement that includes the properties `async: true` and `filter: <filterName>` with `<filterName>` matching the primary function that's being exported.
34+
35+
``` javascript
36+
const myFilter = async (author, callback) => {
37+
const message = { text: "Hello ${author}!" };
38+
const error = null;
39+
return callback(error, message.text);
40+
};
41+
42+
module.exports = {
43+
async: true,
44+
filter: myFilter
45+
}
46+
```
47+
48+
!!! info "Async Error Handling"
49+
Errors reported by async plugins are output to the workflow runner logs. E.g. GitHub Actions, GitLab CI, etc.
50+
51+
Here's how to invoke the new filter from this example, whether it's synchronous or asynchronous:
52+
53+
```yaml+jinja
54+
automations:
55+
welcome_author:
56+
if:
57+
- true
58+
run:
59+
- action: add-comment@v1
60+
args:
61+
comment: {{ pr.author | myFilter }}
62+
```
63+
64+
!!! warning "15 Minute Time Limit"
65+
gitStream actions are terminated after 15 minutes, this is a hard limit that can't be extended.
66+
67+
### Accept Arguments
68+
69+
Filter function plugins can accept any number of arguments. The first argument must be passed to the filter function via a ` | ` operator; all subsequent arguments are passed as a set inside parenthesis.
70+
71+
!!! example "Filter function to combine two strings"
72+
73+
This example accepts two strings and combines them, separating by a space:
74+
75+
```javascript
76+
function combineStrings(str1, str2) {
77+
return str1 + " " + str2;
78+
}
79+
module.exports = combineStrings;
80+
```
81+
82+
In the following invocation, "Hello" is passed as `str1` and "world!" is passed as `str2`
83+
84+
`{{ "Hello" | combineStrings("world!") }}`
85+
86+
### Tips for develpers
87+
88+
1. **Debugging with console.log()**
89+
90+
Any data passed to `console.log()` will be displayed in your workflow runner logs, such as GitHub Actions, GitLab CI, etc.
91+
92+
2. **Context Variable Insight**
93+
94+
Utilize the [gitStream playground](https://app.gitstream.cm/playground) to see how the context variable appears in a real Pull Request (PR). Inspect the PR Context Variables at the bottom of the screen ![Playground](screenshots/playground-context-variables.png).
95+
96+
3. **Local Execution**
97+
98+
- Run the plugin locally for testing, for example: Running `index.js` with Node.js.
99+
```javascript
100+
module.exports = (text) => {
101+
return text.replaceAll('banana', '🍌');
102+
};
103+
104+
const banana = require('./index.js');
105+
console.assert(banana("hello banana!") === 'hello 🍌!', `banana("hello banana!") === 'hello 🍌!' but got ${banana("hello banana!")}`);
106+
```
107+
108+
- Execute with:
109+
```bash
110+
$ node index.js
111+
```
112+
113+
4. **Handling Escaped Characters**
114+
115+
When returning strings with escaped characters, add an extra slash as it will be parsed by the template engine. For example, to return the following text `"first line \n next line"` you should return this from the plugin `"first line \\n next line"`.
116+
117+
!!! tip "Check out the community plugin library."
118+
Check out the [filter function plugin library](/filter-function-plugins) to explore plugins created by the LinearB community.
119+
120+
## Contribute to the Community Plugin Library
121+
122+
LinearB maintains a collection of [community-contributed gitStream plugins](/filter-function-plugins). Here are the instructions for publishing a plugin as part of this library.
123+
124+
Create a directory for your plugin inside one of the subdirectories in `plugins/filters`. The name of the directory must match the name of the exported JavaScript function. Then ensure you have all of the required files and JSDoc content outlined below.
125+
126+
Here is an [example of a well-designed gitStream plugin](https://github.com/linear-b/gitstream/tree/main/plugins/filters/isFlaggedUser).
127+
128+
Required Files:
129+
130+
* index.js - The entry point for your plugin. This should have a main function that is exported via `module.exports` that is documented according to the JSDoc requirements outlined below.
131+
* README.md - Use this [template](https://github.com/linear-b/gitstream/tree/main/docs/templates/filter-readme-template.md).
132+
* reference.md - This file must be auto-generated by `jsdoc2md`, see the instructions below.
133+
* plugin_name.cm - A gitStream CM example that uses the plugin.
134+
* LICENSE - The full text of the open source license the code is provided under.
135+
136+
Required JSDoc tags:
137+
138+
* `@module` - This must match the name of the exported JavaScript function.
139+
* `@description` - A 1-2 line description that wholistically describes the functionality of the plugin.
140+
* `@param` - There should be one `@param` tag for each argument the plugin accepts, with indicated types. Indicate which parameter is the default input parameter with the name "Input."
141+
* `@returns` - Provide the type and a short description.
142+
* `@example` - Simple examples that show how to invoke the plugin.
143+
* `@license` - The name of the lincense contained in the LICENSE file.
144+
145+
Here is an example of properly formatted JSDoc content:
146+
147+
148+
```javascript
149+
/**
150+
* @module isFlaggedUser
151+
* @description Returns true if the username that is passed to this function is specified in a predefined list of users.
152+
* This is useful if you want gitStream automations to run only for specified users.
153+
* @param {string} Input - The GitHub username to check.
154+
* @returns {boolean} Returns true if the user is specified in the flaggedUsers list, otherwise false.
155+
* @example {{ pr.author | isFlaggedUser }}
156+
* @license MIT
157+
**/
158+
```
159+
160+
***How to Generate Plugin Reference Markdown***
161+
162+
You can use jsdoc2md to convert the JSDoc content of your plugin to markdown using templates we've provided. First install jsdoc2md:
163+
164+
```npm install -g jsdoc-to-markdown```
165+
166+
Then, invoke the following command from inside your plugin directory:
167+
168+
```
169+
jsdoc2md --partial ../../../docs/snippets/partials/body.hbs --partial ../../../docs/snippets/partials/sig-name.hbs --files index.js > reference.md
170+
```
171+
172+
This should output a reference.md file that contains properly formatted markdown based on the JSDoc contents of your plugin.

docs/plugins.md

Lines changed: 0 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -88,172 +88,3 @@ If the filter does not expect any arguments, you can invoke it by passing an emp
8888
```
8989
{{ "" | myFilter }}
9090
```
91-
## Create Filter Function Plugins
92-
93-
gitStream plugins are based on the [CommonJS](https://en.wikipedia.org/wiki/CommonJS) module standard, a widely used pattern for structuring and importing JavaScript modules.
94-
95-
!!! info "Supported JavaScript Dependencies"
96-
gitStream supports the following JavaScript dependencies: [axios](https://github.com/axios/axios), github actions core (@actions/core), [moment](https://github.com/moment/moment), [lodash](https://github.com/lodash/lodash), octokit rest api (@octokit/rest)
97-
98-
No other dependencies are supported at this time. If you have recommendations for new dependencies, please open a new issue on the [gitStream GitHub repo](https://github.com/linear-b/gitstream).
99-
100-
### Define a New Plugin
101-
102-
Each filter function plugin must have its own unique directory inside the appropriate `/filters` directory for your repo or organization. To create a new filter function, create an index.js file inside the plugin's top-level directory, all plugins must have an index.js file that serves as the primary entry point
103-
104-
One of the functions contained inside this file must be exported via `module.exports`, using the following conventions:
105-
106-
Export plugins that use synchronous code:
107-
108-
``` javascript
109-
function myFilter(author) {
110-
return "Hello ${author}!";
111-
};
112-
113-
module.exports = myFilter;
114-
```
115-
116-
### Define a New Asynchronous Plugin (async)
117-
118-
When using async JavaScript in your plugin, you need two things:
119-
120-
* A primary async function that returns a `callback()` containing any errors as the first argument and the result of the filter as the second.
121-
* A `module.exports` statement that includes the properties `async: true` and `filter: <filterName>` with `<filterName>` matching the primary function that's being exported.
122-
123-
``` javascript
124-
const myFilter = async (author, callback) => {
125-
const message = { text: "Hello ${author}!" };
126-
const error = null;
127-
return callback(error, message.text);
128-
};
129-
130-
module.exports = {
131-
async: true,
132-
filter: myFilter
133-
}
134-
```
135-
136-
!!! info "Async Error Handling"
137-
Errors reported by async plugins are output to the workflow runner logs. E.g. GitHub Actions, GitLab CI, etc.
138-
139-
Here's how to invoke the new filter from this example, whether it's synchronous or asynchronous:
140-
141-
```yaml+jinja
142-
automations:
143-
welcome_author:
144-
if:
145-
- true
146-
run:
147-
- action: add-comment@v1
148-
args:
149-
comment: {{ pr.author | myFilter }}
150-
```
151-
152-
!!! warning "15 Minute Time Limit"
153-
gitStream actions are terminated after 15 minutes, this is a hard limit that can't be extended.
154-
155-
### Accept Arguments
156-
157-
Filter function plugins can accept any number of arguments. The first argument must be passed to the filter function via a ` | ` operator; all subsequent arguments are passed as a set inside parenthesis.
158-
159-
!!! example "Filter function to combine two strings"
160-
161-
This example accepts two strings and combines them, separating by a space:
162-
163-
```javascript
164-
function combineStrings(str1, str2) {
165-
return str1 + " " + str2;
166-
}
167-
module.exports = combineStrings;
168-
```
169-
170-
In the following invocation, "Hello" is passed as `str1` and "world!" is passed as `str2`
171-
172-
`{{ "Hello" | combineStrings("world!") }}`
173-
174-
### Tips for develpers
175-
176-
1. **Debugging with console.log()**
177-
178-
Any data passed to `console.log()` will be displayed in your workflow runner logs, such as GitHub Actions, GitLab CI, etc.
179-
180-
2. **Context Variable Insight**
181-
182-
Utilize the [gitStream playground](https://app.gitstream.cm/playground) to see how the context variable appears in a real Pull Request (PR). Inspect the PR Context Variables at the bottom of the screen ![Playground](screenshots/playground-context-variables.png).
183-
184-
3. **Local Execution**
185-
186-
- Run the plugin locally for testing, for example: Running `index.js` with Node.js.
187-
```javascript
188-
module.exports = (text) => {
189-
return text.replaceAll('banana', '🍌');
190-
};
191-
192-
const banana = require('./index.js');
193-
console.assert(banana("hello banana!") === 'hello 🍌!', `banana("hello banana!") === 'hello 🍌!' but got ${banana("hello banana!")}`);
194-
```
195-
196-
- Execute with:
197-
```bash
198-
$ node index.js
199-
```
200-
201-
4. **Handling Escaped Characters**
202-
203-
When returning strings with escaped characters, add an extra slash as it will be parsed by the template engine. For example, to return the following text `"first line \n next line"` you should return this from the plugin `"first line \\n next line"`.
204-
205-
206-
!!! tip "Check out the community plugin library."
207-
Check out the [filter function plugin library](/filter-function-plugins) to explore plugins created by the LinearB community.
208-
209-
## Contribute to the Community Plugin Library
210-
211-
LinearB maintains a collection of [community-contributed gitStream plugins](/filter-function-plugins). Here are the instructions for publishing a plugin as part of this library.
212-
213-
Create a directory for your plugin inside one of the subdirectories in `plugins/filters`. The name of the directory must match the name of the exported JavaScript function. Then ensure you have all of the required files and JSDoc content outlined below.
214-
215-
Here is an [example of a well-designed gitStream plugin](https://github.com/linear-b/gitstream/tree/main/plugins/filters/isFlaggedUser).
216-
217-
Required Files:
218-
219-
* index.js - The entry point for your plugin. This should have a main function that is exported via `module.exports` that is documented according to the JSDoc requirements outlined below.
220-
* README.md - Use this [template](https://github.com/linear-b/gitstream/tree/main/docs/templates/filter-readme-template.md).
221-
* reference.md - This file must be auto-generated by `jsdoc2md`, see the instructions below.
222-
* plugin_name.cm - A gitStream CM example that uses the plugin.
223-
* LICENSE - The full text of the open source license the code is provided under.
224-
225-
Required JSDoc tags:
226-
227-
* `@module` - This must match the name of the exported JavaScript function.
228-
* `@description` - A 1-2 line description that wholistically describes the functionality of the plugin.
229-
* `@param` - There should be one `@param` tag for each argument the plugin accepts, with indicated types. Indicate which parameter is the default input parameter with the name "Input."
230-
* `@returns` - Provide the type and a short description.
231-
* `@example` - Simple examples that show how to invoke the plugin.
232-
* `@license` - The name of the lincense contained in the LICENSE file.
233-
234-
Here is an example of properly formatted JSDoc content:
235-
236-
237-
```javascript
238-
/**
239-
* @module isFlaggedUser
240-
* @description Returns true if the username that is passed to this function is specified in a predefined list of users.
241-
* This is useful if you want gitStream automations to run only for specified users.
242-
* @param {string} Input - The GitHub username to check.
243-
* @returns {boolean} Returns true if the user is specified in the flaggedUsers list, otherwise false.
244-
* @example {{ pr.author | isFlaggedUser }}
245-
* @license MIT
246-
**/
247-
```
248-
249-
***How to Generate Plugin Reference Markdown***
250-
251-
You can use jsdoc2md to convert the JSDoc content of your plugin to markdown using templates we've provided. First install jsdoc2md:
252-
253-
```npm install -g jsdoc-to-markdown```
254-
255-
Then, invoke the following command from inside your plugin directory:
256-
257-
`jsdoc2md --partial ../../../docs/snippets/partials/body.hbs --partial ../../../docs/snippets/partials/sig-name.hbs --files index.js > reference.md`
258-
259-
This should output a reference.md file that contains properly formatted markdown based on the JSDoc contents of your plugin.

mkdocs.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ nav:
2626
- Automation actions: automation-actions.md
2727
- Plugins:
2828
- Overview: plugins.md
29-
- Filter Functions Plugins: filter-function-plugins.md
29+
- Plugins Development: plugins-for-developers.md
30+
- Filter Functions Plugins List: filter-function-plugins.md
3031
- Playground: gitStream-playground.md
3132
- Troubleshooting: troubleshooting.md
3233
- FAQ: faq.md

0 commit comments

Comments
 (0)