Skip to content

Commit 328da81

Browse files
authored
Initial commit
0 parents  commit 328da81

File tree

12 files changed

+390
-0
lines changed

12 files changed

+390
-0
lines changed

.github/CONTRIBUTING.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
This repository is not accepting contributions. We’re releasing the code for others
2+
to refer to and learn from, but we are not open to pull requests or issues at
3+
this time.
4+
5+
Khan Academy is a non-profit organization with a mission to provide a free,
6+
world-class education to anyone, anywhere. You can help us in that mission by
7+
[donating](https://khanacademy.org/donate) or looking at
8+
[career opportunities](https://khanacademy.org/careers).

.github/Gerald-README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Gerald Usage Documentation
2+
3+
NOTE: Some of these links point to documents that external users aren't able to access.
4+
5+
Gerald is the project described under [Architectural Decision Record #356](https://docs.google.com/document/d/1TDE_nmrV3vuGi54HtC8X7irSMwTTcc9p83cuhH4kB6Y/edit#heading=h.zcx77itbdtis). The goal of this project is to create a GitHub replacement for Phabricator's Herald functionality.
6+
7+
The code for the project exists in the [Gerald repository](https://github.com/Khan/gerald).
8+
9+
## Overview
10+
11+
Gerald is the name given to the custom GitHub Actions and code that reads in and handles **Notification Rules** and **Reviewer Rules** from the `.github/NOTIFIED` and `.github/REVIEWERS` files, respectively.
12+
13+
Every rule has a condition and a list of GitHub usernames or team slugs. Every time a pull request is made, Gerald will test the files changed, and the squashed diff of the pull request, against all of the rules in the NOTIFIED and REVIEWERS files. Rules that test positive against the pull request are pulled into a list of notifyees and reviewers, depending on the file that the rule exists in. People in this list will be mentioned on the pull request, and reviews will be requested from the list of reviewers.
14+
15+
Every time the pull request is updated, Gerald will rerun and update the pull request comments with a new list of notifyees and reviewers. Commenting #removeme on the pull request will stop Gerald from tagging you in the pull request.
16+
17+
## Adding a Rule
18+
19+
Rules should be added to `.github/NOTIFIED` or `.github/REVIEWERS`. Similar to the [Github CODEOWNERS syntax](https://docs.github.com/en/enterprise/2.15/user/articles/about-code-owners#:~:text=CODEOWNERS%20syntax,org%2Fteam%2Dname%20format.), rules are split by new lines, and comments are made with #. Unlike the CODEOWNERS syntax, the order of a rule does not matter; no rules take precedence over others. Gerald also supports Regular Expressions and suffixing usernames and team slugs with an exclamation point to denote a required reviewer.
20+
21+
Rules are made in the format of:
22+
`<pattern> @<username or Organization/team-slug>`
23+
24+
Make sure that you escape any '@'s that you're using for anything other than a Github username, so that it doesn't read it as a Github username!
25+
26+
### File matching with Glob patterns
27+
28+
Adding yourself to these files will notify you or make you a reviewer of any pull-requests to the current working branch that affect the files/folders matched.
29+
30+
These files support typical [glob functionality](https://www.npmjs.com/package/fast-glob#pattern-syntax) with [dot](https://www.npmjs.com/package/fast-glob#dot) turned on.
31+
32+
### Diff matching with Regular Expressions
33+
34+
In addition to glob patterns, Gerald rules also support Regular Expressions. Regular Expressions will be tested against the `diff` of a file. Regular Expressions should be surrounded with double quotes.
35+
`"/^find me!$/ig" @<username or Organization/team-slug>`
36+
37+
## On Pull Request vs. On Push Without Pull Request
38+
39+
In `.github/REVIEWERS`, all rules are run when a pull request is created, because only pull requests can have reviewers. In `.github/NOTIFIED`, rules under the `[ON PULL REQUEST]` section will be run when a pull request is made. Rules under the `[ON PUSH WITHOUT PULL REQUEST]` section will be run whenever someone pushes directly to a list of protected branches. By default, that list is `master`, `main`, and `develop`.
40+
41+
## Required Reviewers
42+
43+
Developers using Gerald in conjunction with [Khan's custom command line tools](https://github.com/Khan/our-lovely-cli) can also specify if someone is a required reviewer. In the `.github/REVIEWERS` file, adding an exclamation point to the end of a username or team slug will make them a required reviewer. This is enforced in OLC's `git land` command, which will check for approval from required reviewers before landing pull requests.
44+
`important-file.js @<username or Organization/team-slug>!`
45+
46+
## Pattern Examples
47+
48+
### Matching a single file
49+
50+
The most efficient way of matching a single file would be to provide entire path relative to the root directory of the workspace.
51+
`./src/packages/important-file.js @<username or Organization/team-slug>`
52+
53+
### Matching an entire directory
54+
55+
There are three ways to match for files in a directory.
56+
57+
1. `./src` will match only the `./src` directory and no files in the directory.
58+
2. `./src/*` will match all files and directories in the `./src` folder, but it will not match `./src/directory/file.js`, for example.
59+
3. `./src/**` will match all files in the `./src` directory, however deeply nested.
60+
61+
## Testing Gerald Rules
62+
63+
If you've set up the [`git gerald-tester` command](./Setup-README.md), you can test out a Gerald rule by running `git gerald-tester --glob` or `git gerald-tester --regex`. Doing so will prompt you for a Glob pattern or Regular Expression, based on the flag you passed in, allowing you to test out patterns before adding them to the Gerald files.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
name: Not Accepting Contributions
3+
about: 'Warning: This repo isn''t accepting contributions at this time.'
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
This repository is not accepting contributions. We’re releasing the code for others
11+
to refer to and learn from, but we are not open to pull requests or issues at
12+
this time.
13+
14+
Issues can be filed to share information, but we cannot guarantee any response.

.github/NOTIFIED

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
[NOTIFY RULES]
2+
3+
Be sure to read through https://khanacademy.atlassian.net/wiki/spaces/FRONTEND/pages/598278672/Gerald+Documentation before adding any rules!
4+
5+
Examples:
6+
7+
# This rule will notify @owner1 on changes to all files
8+
# **/* @owner1
9+
10+
# This rule will notify @owner1 and @Org/team1 on changes to all .js files
11+
# **/*.js @owner1 @Org/team1
12+
13+
# This rule will notify @owner1 and @owner2 on changes to all files in the src/ directory. It will not match files in nested directories, such as src/about/about.js
14+
# src/* @owner1 @owner2
15+
16+
# This rule will notify @owner1 and @owner2 on changes to all files in the src/ directory, recursively. In contrast to the rule above, it WILL match src/about/about.js
17+
# src/** @owner1 @owner2
18+
19+
# This rule will notify @owner1 on changes to all files that have the word "gerald" in its name
20+
# **/*gerald* @owner1
21+
22+
# The following rules will both notify @owner1 on changes to any file that ends with .js, .txt, or .yml
23+
# **/*.(js|txt|yml) @owner1 # This is in the style of Regex groups (https://www.regular-expressions.info/brackets.html)
24+
# **/*.{js,txt,yml} @owner1 # This is in the style of Bash brace expansions (https://github.com/micromatch/braces)
25+
26+
# This rule will notify @owner1 on changes made to main.js or main.test.js. Read more about extended globbing: https://github.com/micromatch/micromatch#extglobs
27+
# main?(.test).js @owner1
28+
29+
# This rule will notify @owner1 on changes made to file-1, file-2, and file-3.
30+
# file-[1-5] @owner1 # This is in the style of Regex character glasses (https://github.com/micromatch/micromatch#regex-character-classes)
31+
32+
# This rule will notify @owner1 on changes made to file-0, file-2, file-3, ..., file-9.
33+
# file-[[:digit:]] @owner1 # This uses POSIX character classes (https://github.com/micromatch/picomatch#posix-brackets)
34+
35+
Regex Examples:
36+
37+
# This rule will notify @owner1 on changes that include the word "gerald"
38+
# "/gerald/ig" @owner1
39+
40+
# This rule will notify @owner1 on changes that *add* the word "gerald"
41+
# "/^\+.*gerald/igm" @owner1
42+
43+
# This rule will notify @owner1 on changes that *remove* the word "gerald"
44+
# "/^\-.*gerald/igm" @owner1
45+
46+
# This rule will notify @owner1 on changes that *add OR remove* the word "gerald"
47+
# "/^(\-|\+).*gerald/igm" @owner1
48+
49+
----Everything above this line will be ignored!----
50+
[ON PULL REQUEST] (DO NOT DELETE THIS LINE)
51+
52+
# Notify these people for any changes made to any file
53+
54+
55+
56+
[ON PUSH WITHOUT PULL REQUEST] (DO NOT DELETE THIS LINE)
57+
58+
# Adding yourself below this line will notify you of any changes to this branch that don't go through a pull-request.
59+
# This is analogous to Herald's "Differential Revision is False" condition.
60+

.github/REVIEWERS

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
[<REQUIRED> REVIEWER RULES]
2+
3+
Be sure to read through https://khanacademy.atlassian.net/wiki/spaces/FRONTEND/pages/598278672/Gerald+Documentation before adding any rules!
4+
5+
Examples:
6+
7+
# This rule will request @owner1 for review on changes to all files. This rule will also request @owner2 for a blocking review.
8+
# **/* @owner1 @owner2!
9+
10+
# This rule will request @owner1 and @Org/team1 for review on changes to all .js files
11+
# **/*.js @owner1 @Org/team1
12+
13+
# This rule will request @owner1 and @owner2 for review on changes to all files in the src/ directory. It will not match files in nested directories, such as src/about/about.js
14+
# src/* @owner1 @owner2
15+
16+
# This rule will request @owner1 and @owner2 for review on changes to all files in the src/ directory, recursively. In contrast to the rule above, it WILL match src/about/about.js
17+
# src/** @owner1 @owner2
18+
19+
# This rule will request @owner1 for review on changes to all files that have the word "gerald" in its name
20+
# **/*gerald* @owner1
21+
22+
# The following rules will both request @owner1 for review on changes to any file that ends with .js, .txt, or .yml
23+
# **/*.(js|txt|yml) @owner1 # This is in the style of Regex groups (https://www.regular-expressions.info/brackets.html)
24+
# **/*.{js,txt,yml} @owner1 # This is in the style of Bash brace expansions (https://github.com/micromatch/braces)
25+
26+
# This rule will request @owner1 for review on changes made to main.js or main.test.js. Read more about extended globbing: https://github.com/micromatch/micromatch#extglobs
27+
# main?(.test).js @owner1
28+
29+
# This rule will request @owner1 for review on changes made to file-1, file-2, and file-3.
30+
# file-[1-5] @owner1 # This is in the style of Regex character glasses (https://github.com/micromatch/micromatch#regex-character-classes)
31+
32+
# This rule will request @owner1 for review on changes made to file-0, file-2, file-3, ..., file-9.
33+
# file-[[:digit:]] @owner1 # This uses POSIX character classes (https://github.com/micromatch/picomatch#posix-brackets)
34+
35+
Regex Examples:
36+
37+
# This rule will request @owner1 for review on changes that include the word "gerald"
38+
# "/gerald/ig" @owner1
39+
40+
# This rule will request @owner1 for review on changes that *add* the word "gerald"
41+
# "/^\+.*gerald/igm" @owner1
42+
43+
# This rule will request @owner1 for review on changes that *remove* the word "gerald"
44+
# "/^\-.*gerald/igm" @owner1
45+
46+
# This rule will request @owner1 for review on changes that *add OR remove* the word "gerald"
47+
# "/^(\-|\+).*gerald/igm" @owner1
48+
49+
----Everything above this line will be ignored!----
50+
[ON PULL REQUEST] (DO NOT DELETE THIS LINE)
51+

.github/pull_request_template.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## Summary:
2+
3+
Issue: XXX-1234
4+
5+
## Test plan:

.github/workflows/gerald-comment.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Gerald - Check Comments
2+
'on':
3+
issue_comment
4+
jobs:
5+
gerald:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- name: Run Gerald
9+
uses: Khan/gerald@main
10+
env:
11+
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
12+
ADMIN_PERMISSION_TOKEN: '${{ secrets.KHAN_ACTIONS_BOT_TOKEN }}'
13+
EVENT: 'issue_comment'

.github/workflows/gerald-pr.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Gerald - Notify and Request Reviewers On Pull Request
2+
'on':
3+
pull_request:
4+
# ready_for_review isn't included by default, so we add it
5+
# here to have this workflow re-run when a pr is converted
6+
# from "draft" to "not draft".
7+
# We also add "edited" to re-check when the base branch
8+
# is changed.
9+
types: [opened, synchronize, reopened, ready_for_review, edited]
10+
11+
jobs:
12+
gerald:
13+
# Don't re-run if only the title or body changes
14+
if: "github.event.action != 'edited' || github.event.changes.base != null"
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: Khan/actions@gerald-pr-v3
18+
with:
19+
token: ${{ secrets.GITHUB_TOKEN }}
20+
admin-token: ${{ secrets.KHAN_ACTIONS_BOT_TOKEN }}

.github/workflows/gerald-push.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Gerald - Notify on Push
2+
'on':
3+
push:
4+
branches:
5+
- master
6+
- develop
7+
- main
8+
jobs:
9+
gerald:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
with:
14+
ref: '${{ github.ref }}'
15+
# GitHub Actions doesn't allow us to take the length of github.event.commits, so we have to pass the array into node and take the length there.
16+
# We add one to the length because we want to get the diff between the last commit and the commit before the first commit.
17+
fetch-depth: '$(node -e "console.log(${{ github.event.commits }}.length + 1)")'
18+
- name: Run Gerald
19+
uses: Khan/gerald@main
20+
env:
21+
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
22+
ADMIN_PERMISSION_TOKEN: '${{ secrets.KHAN_ACTIONS_BOT_TOKEN }}'
23+
EVENT: 'push'

.gitignore

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
9+
# Diagnostic reports (https://nodejs.org/api/report.html)
10+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Directory for instrumented libs generated by jscoverage/JSCover
19+
lib-cov
20+
21+
# Coverage directory used by tools like istanbul
22+
coverage
23+
*.lcov
24+
25+
# nyc test coverage
26+
.nyc_output
27+
28+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29+
.grunt
30+
31+
# Bower dependency directory (https://bower.io/)
32+
bower_components
33+
34+
# node-waf configuration
35+
.lock-wscript
36+
37+
# Compiled binary addons (https://nodejs.org/api/addons.html)
38+
build/Release
39+
40+
# Dependency directories
41+
node_modules/
42+
jspm_packages/
43+
44+
# TypeScript v1 declaration files
45+
typings/
46+
47+
# TypeScript cache
48+
*.tsbuildinfo
49+
50+
# Optional npm cache directory
51+
.npm
52+
53+
# Optional eslint cache
54+
.eslintcache
55+
56+
# Microbundle cache
57+
.rpt2_cache/
58+
.rts2_cache_cjs/
59+
.rts2_cache_es/
60+
.rts2_cache_umd/
61+
62+
# Optional REPL history
63+
.node_repl_history
64+
65+
# Output of 'npm pack'
66+
*.tgz
67+
68+
# Yarn Integrity file
69+
.yarn-integrity
70+
71+
# dotenv environment variables file
72+
.env
73+
.env.test
74+
75+
# parcel-bundler cache (https://parceljs.org/)
76+
.cache
77+
78+
# Next.js build output
79+
.next
80+
81+
# Nuxt.js build / generate output
82+
.nuxt
83+
dist
84+
85+
# Gatsby files
86+
.cache/
87+
# Comment in the public line in if your project uses Gatsby and *not* Next.js
88+
# https://nextjs.org/blog/next-9-1#public-directory-support
89+
# public
90+
91+
# vuepress build output
92+
.vuepress/dist
93+
94+
# Serverless directories
95+
.serverless/
96+
97+
# FuseBox cache
98+
.fusebox/
99+
100+
# DynamoDB Local files
101+
.dynamodb/
102+
103+
# TernJS port file
104+
.tern-port

0 commit comments

Comments
 (0)