Skip to content

Commit 04e4899

Browse files
Merge pull request #530 from linear-b/checklist-plugin
Create checklist plugin
2 parents 3a20177 + 61fa14f commit 04e4899

File tree

9 files changed

+203
-0
lines changed

9 files changed

+203
-0
lines changed

docs/automations/automation-library.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ This library of gitStream examples is meant to serve as a starting point for you
3232
* [Label missing project tracker](label-missing-project-tracker/README.md) - Flag PRs that are missing a reference to an associated project tracking resource.
3333
* [Automatic project tracking links](standard/link-issue-tracker/README.md) - Automatically post PR comments that link to the associated project tracking resource (Jira, Shortcut, Azure Boards, and more).
3434
* [Summarize PR contents by language](standard/summarize-language-changes/README.md) - Post a comment that breaks down code changes by the programming languages contained in the PR.
35+
* [PR Checklist](pr-checklist-general/README.md) - Post a comment with a checklist giving more context about the PR to reviewers
3536

3637
## Improve PR Quality
3738
### Merge Routing
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
title: Automation - PR Checklist General
3+
description: Automatically evaluate PRs against code requirement checklists.
4+
---
5+
# PR Checklist General
6+
7+
<!-- --8<-- [start:example]-->
8+
Automatically evaluate PRs against code requirement checklists.
9+
10+
<div class="automationImage" markdown="1">
11+
![PR Checklist General](/automations/standard/pr-checklist-general/pr-checklist-general.png)
12+
</div>
13+
<div class="automationDescription" markdown="1">
14+
!!! info "Configuration Description"
15+
There are no conditions for this action - if included as presented in the demo, it's run every time.
16+
17+
Automation Actions:
18+
19+
* Post a comment containing a checklist with each completed item checked off.
20+
21+
</div>
22+
<div class="automationExample" markdown="1">
23+
!!! example "PR Checklist General"
24+
```yaml+jinja
25+
--8<-- "docs/downloads/automation-library/pr_checklist_general.cm"
26+
```
27+
<div class="result" markdown>
28+
<span>
29+
[:octicons-download-24: Download this example as a CM file.](/downloads/automation-library/pr_checklist_general.cm){ .md-button }
30+
</span>
31+
</div>
32+
</div>
33+
<!-- --8<-- [end:example]-->
34+
35+
## Additional Resources
36+
37+
--8<-- "docs/snippets/general.md"
38+
39+
--8<-- "docs/snippets/automation-footer.md"
Loading
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# -*- mode: yaml -*-
2+
3+
manifest:
4+
version: 1.0
5+
6+
automations:
7+
checklist:
8+
if:
9+
- true
10+
run:
11+
- action: add-comment@v1
12+
args:
13+
comment: {{ "" | checklist(branch, files, pr, repo, env, source) }}

docs/filter-function-plugins.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ description: Implement custom gitStream filter functions with JavaScript.
66

77
JavaScript plugins that enable custom filter functions for gitStream. To learn how to use these examples, read our [guide on how to use gitStream plugins](/plugins).
88

9+
--8<-- "plugins/filters/checklist/README.md"
10+
911
--8<-- "plugins/filters/compareMultiSemver/README.md"
1012

1113
--8<-- "plugins/filters/compareSemver/README.md"

plugins/filters/checklist/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 LinearB
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

plugins/filters/checklist/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--8<-- "plugins/filters/checklist/reference.md"
2+
3+
With this plugin, you can easily customize the checklist using the object in the JavaScript code. To add a new check to the list, just add a new object with a descriptive `title` for your own benefit, a `label` that'll get posted in the comment, and the `condition` that, if true, would cause the entry in the checklist to be checked off.
4+
5+
??? note "Plugin Code: checklist"
6+
```javascript
7+
--8<-- "plugins/filters/checklist/index.js"
8+
```
9+
<div class="result" markdown>
10+
<span>
11+
</span>
12+
</div>
13+
14+
15+
??? example "gitStream CM Example: checklist"
16+
```yaml+jinja
17+
--8<-- "docs/downloads/automation-library/pr_checklist_general.cm"
18+
```
19+
<div class="result" markdown>
20+
<span>
21+
</span>
22+
</div>
23+
24+
[Download Source Code](https://github.com/linear-b/gitstream/tree/main/plugins/filters/checklist)
25+
26+

plugins/filters/checklist/index.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* @module checklist
3+
* @description Automatically check PRs against a checklist of conditions.
4+
* This is useful if you want to ensure that PRs meet certain criteria before they can be merged.
5+
* @param {string} Input - A blank string (no input variable is required)
6+
* @param {object} branch - The branch context variable.
7+
* @param {object} files - The files context variable.
8+
* @param {object} pr - The pr context variable.
9+
* @param {object} repo - The repo context variable.
10+
* @param {object} env - The env context variable.
11+
* @param {object} source - The source context variable.
12+
* @returns {string} Returns a formatted GitHub comment with a checklist of conditions that the PR meets.
13+
* @example
14+
* - action: add-comment@v1
15+
args:
16+
comment: {{ "" | checklist(branch, files, pr, repo, env, source) }}
17+
* @license MIT
18+
**/
19+
20+
const checklistFilter = async (empty, branch, files, pr, repo, env, source, callback) => { // made sync temporarily
21+
22+
const checks = [
23+
{
24+
title: "low-risk",
25+
label: "The PR is a low-risk change",
26+
// our sample definition of a low-risk change is a docs-only PR from designated docs writers
27+
condition: files.every(file => /docs\//.test(file)) && pr.author_teams.includes("tech-writers")
28+
},
29+
{
30+
title: "has-jira",
31+
label: "The PR has a Jira reference in the title",
32+
condition: /\b[A-Za-z]+-\d+\b/.test(pr.title)
33+
},
34+
{
35+
title: "updates-tests",
36+
label: "The PR includes updates to tests",
37+
condition: files.some(file => /[^a-zA-Z0-9](spec|test|tests)[^a-zA-Z0-9]/.test(file))
38+
},
39+
{
40+
title: "includes-docs",
41+
label: "The PR includes changes to the documentation",
42+
condition: files.some(file => /docs\//.test(file))
43+
},
44+
{
45+
title: "first-time",
46+
label: "The PR author is a first-time contributor",
47+
condition: repo.author_age < 1 && repo.age > 0 // if the PR author made their first contirbution on the current day
48+
},
49+
{
50+
title: "requires-opsec",
51+
label: "The PR doesn't expose any secrets",
52+
condition: source.diff.files
53+
.map(file => file.new_content)
54+
.every(file_content =>
55+
[
56+
"MY_SECRET_ENVIRONMENT_VARIABLE"
57+
].every(env_var => !file_content.includes(env_var))
58+
// nothing added to any file during this comment contains any of the secret environment variables in this array
59+
)
60+
}
61+
];
62+
63+
const comment = await Promise.resolve(checks
64+
.map(check => `- [${check.condition ? "x" : " "}] ${check.label}`)
65+
.join("\n"));
66+
67+
return callback(
68+
null,
69+
JSON.stringify(comment)
70+
);
71+
};
72+
73+
module.exports = {
74+
async: true,
75+
filter: checklistFilter
76+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<a name="module_checklist"></a>
2+
3+
## checklist
4+
Automatically check PRs against a checklist of conditions.
5+
This is useful if you want to ensure that PRs meet certain criteria before they can be merged.
6+
7+
**Returns**: <code>string</code> - Returns a formatted GitHub comment with a checklist of conditions that the PR meets.
8+
**License**: MIT
9+
10+
| Param | Type | Description |
11+
| --- | --- | --- |
12+
| Input | <code>string</code> | A blank string (no input variable is required) |
13+
| branch | <code>object</code> | The branch context variable. |
14+
| files | <code>object</code> | The files context variable. |
15+
| pr | <code>object</code> | The pr context variable. |
16+
| repo | <code>object</code> | The repo context variable. |
17+
| env | <code>object</code> | The env context variable. |
18+
| source | <code>object</code> | The source context variable. |
19+
20+
**Example**
21+
```js
22+
- action: add-comment@v1
23+
args:
24+
comment: {{ "" | checklist(branch, files, pr, repo, env, source) }}
25+
```

0 commit comments

Comments
 (0)