├── .babelrc
├── .gitignore
├── README.md
├── fixtures
├── installation_repositories.added.json
├── lambda-test-event.json
├── pull_request.opened.json
├── pull_request.synchronize.json
└── push.json
├── index.js
├── lambda-test.js
├── logs
└── .gitignore
├── nodemon.json
├── package.json
├── scripts
├── compare-commits.js
├── deploy.sh
├── get-logs.js
├── phpcs.js
├── test-commit.js
└── test-pr.js
├── src
├── config.js
├── diff.js
├── format.js
├── hooks.js
├── index.js
├── linters
│ ├── eslint
│ │ └── index.js
│ ├── index.js
│ ├── phpcs
│ │ └── index.js
│ └── stylelint
│ │ └── index.js
├── metadata.js
├── review.js
├── run.js
└── util.js
└── start-development.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["transform-async-to-generator"],
3 | "presets": ["es2015", "stage-0"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pem
2 | .env
3 | build/
4 | node_modules
5 | probot/
6 | src/linters/phpcs/vendor
7 | bin/
8 | lib/
9 | event.json
10 | lambda-function.zip
11 | package-lock.json
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | hm-linter bot
5 | Automatically run the HM Coding Standards on any repository.
6 | |
7 |
8 | 🤖
9 | |
10 |
11 |
12 |
13 | A Human Made project. Maintained by @rmccue.
14 | |
15 |
16 |
17 | |
18 |
19 |
20 |
21 | Automatically run the [HM Coding standards](https://github.com/humanmade/coding-standards) on any repository.
22 |
23 |
24 |
25 |
26 | ## Installation
27 |
28 | To enable on any repository on GitHub, simply [head to the app page](https://github.com/apps/hm-linter) and Install/Configure. You'll get an initial report as a new issue if you have any existing linting errors in your codebase.
29 |
30 | Every repository is different, and you might want to customise the rules that the linter runs. Good news: you can do just that. hm-linter detects custom configuration files automatically, just create a `phpcs.ruleset.xml` file for phpcs, [`eslintrc.*`](https://eslint.org/docs/user-guide/configuring#configuration-file-formats) file for ESLint, or [`.stylelintrc`](https://stylelint.io/user-guide/configure) for stylelint.
31 |
32 | See the [HM Coding standards](https://github.com/humanmade/coding-standards) documentation for how to configure specific rules.
33 |
34 | **Note:** Custom configuration can only use rules/standards which hm-linter has available. This includes the HM Coding Standards as well as any dependencies of it (such as the WP Coding Standards).
35 |
36 |
37 | ## Configuration
38 |
39 | By default, hmlinter will use the latest version of the Human Made coding standards. You can configure it to use an older or fixed version by creating a `.github/hmlinter.yml` file. This file should look like:
40 |
41 | ```yaml
42 | # GLOBAL SETTINGS
43 |
44 | # By default, the version is set to "latest". This can be set to any version
45 | # from 0.4.2 and above, but you MUST include the full version number.
46 | # If you wish to increase the security releases automatically set the
47 | # version to be 'X.Y', otherwise it will be 'X.Y.Z'.
48 | version: latest
49 |
50 | # PER-STANDARD SETTINGS
51 | phpcs:
52 | # Set to false to disable phpcs
53 | enabled: true
54 |
55 | # Set to "inherit" to use the global version, "latest" for the latest
56 | # version, or a specific full version number.
57 | version: inherit
58 |
59 | eslint:
60 | enabled: true
61 | version: inherit
62 |
63 | stylelint:
64 | enabled: true
65 | version: inherit
66 | ```
67 |
68 | Versions **MUST** be specified in full format (i.e. `0.5.0`). `latest` is available as a convenient shorthand for the latest published version, but note that this will be updated and may cause your code to fail future checks.
69 |
70 |
71 | ## Development
72 |
73 | hm-linter is a GitHub bot built on top of the [Probot framework](https://probot.github.io/). It runs on Lambda, which runs Node 12.x.
74 |
75 | To get started on development of hm-linter:
76 |
77 | 1. Clone this repository
78 | 2. `npm install` or `yarn install` the dependencies
79 |
80 |
81 | ## Testing
82 |
83 | ### Live Testing
84 |
85 | The easiest and best way to test hm-linter is to run the bot in development mode. This will run the bot locally, and uses a proxy to forward all webhook events from GitHub.
86 |
87 | `yarn start` will run a development copy of the linter bot inside a Lambda-like Docker container.
88 |
89 | To set this up:
90 |
91 | 1. Download "hm-linter-development Private Key" from the team 1Password Documents.
92 | 2. Save this file into the linter-bot directory as `development.private-key.pem`
93 | 3. Download "hm-linter-development .env" from the team 1Password Documents.
94 | 4. Save this file into the linter-bot directory as `.env`
95 | 5. Run `yarn start`
96 |
97 | The development mode is set up only on the [linter-bot-test](https://github.com/humanmade/linter-bot-test) repository. You can add it to other repositories on the `humanmade` organisation, but **please only do this temporarily**. You should remove any repositories you add as soon as you're finished testing.
98 |
99 | Webhook events for the development bot are sent to Smee.io, which [logs all events](https://smee.io/rpFoxbfDjkw5Srji). If you visit this page, you can also replay events; you should use this while developing/testing rather than repeatedly opening new PRs.
100 |
101 | A typical development process looks like this:
102 |
103 | 1. Generate the test event you want or find one that already exists
104 | 2. Write the first version of your code to handle it
105 | 3. `yarn start`
106 | 4. [Replay the event on Smee](https://smee.io/rpFoxbfDjkw5Srji)
107 | 5. Check that your code did what you expect
108 | 6. If your code worked, you're done 🙌
109 | 7. If your code didn't work, kill the bot
110 | 8. Repeat steps 2-7 until your code works.
111 |
112 |
113 | ### Replicating production issues
114 |
115 | The first step to replicating production issues is to understand the request being sent to hm-linter. Note that when running against these events, you are **testing against the live GitHub API**, so be careful.
116 |
117 | Access the CloudWatch Logs for hm-linter (ask the Cloud team for access) and find the request you received. If you have the AWS CLI installed, you can do this by running the `scripts/get-logs.js` command.
118 |
119 | Each check status page lists the various request IDs. The **Lambda ID** is the ID you need for pulling down the relevant logs and data.
120 |
121 | This will write the logs to `{id}.log`, and save the raw data to `{id}.json`.
122 |
123 | ```sh
124 | # For request deadbeef-badd-ecaf-dead-beefbaddecaf:
125 | node scripts/get-logs.js deadbeef-badd-ecaf-dead-beefbaddecaf
126 |
127 | # By default, this will only check the last 48 hours; to override, set HOUR_LIMIT:
128 | HOUR_LIMIT=192 node scripts/get-logs.js deadbeef-badd-ecaf-dead-beefbaddecaf
129 | ```
130 |
131 | ```
132 | Querying for deadbeef-badd-ecaf-dead-beefbaddecaf
133 | Waiting for results…
134 | Log saved to: deadbeef-badd-ecaf-dead-beefbaddecaf.log
135 | Raw data saved to: deadbeef-badd-ecaf-dead-beefbaddecaf.json
136 | ```
137 |
138 | You can then run the handler against a simulated Lambda environment locally (using Docker):
139 |
140 | ```
141 | # Run build at least once:
142 | npm run build
143 |
144 | # Run the handler.
145 | npm run test < deadbeef-badd-ecaf-dead-beefbaddecaf.json
146 | ```
147 |
148 | **Note:** The format of the JSON data passed to `test` **must** be in API Gateway format (i.e. from the get-logs script). If you get an `Cannot read property 'x-github-event' of undefined` error, you're passing a GitHub event instead (i.e. from Smee).
149 |
150 |
151 | ### Deployment
152 |
153 | hm-linter is deployed on a Lambda instance. Deployment is handled via npm scripts, which you run via `npm run