Skip to content

Commit 7c345a2

Browse files
committed
add developing checks guide
1 parent d7f19b3 commit 7c345a2

File tree

13 files changed

+4078
-3
lines changed

13 files changed

+4078
-3
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ Expect more docs soon...
3030

3131
1. [Getting started](getting-started.md)
3232
1. [How does it work?](how-does-it-work.md)
33-
1. [How to build X?](how-to-build-X.md)
3433
1. [Configuration — codechecks.json/ts/js](configuration.md)
35-
1. Checks (plugins) development
34+
1. [Checks (plugins) development](developing-checks.md)
3635
1. Developing reusable checks
3736
1. Testing checks
37+
1. [How to build X?](how-to-build-X.md)
3838
1. Client API reference
3939
1. [FAQ](faq.md)
4040
1. Roadmap

developing-checks.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Developing checks
2+
3+
In this tutorial we are gonna build simplified version of
4+
[build-size-watcher](https://github.com/codechecks/build-size-watcher). It's gonna be able just to
5+
watch size of a single file and doesn't support gzip. We are gonna use yarn in this tutorial but you
6+
can pick npm as well. Lets' start!
7+
8+
We want our check to be fully reusable so we are gonna create new npm package just for it.
9+
10+
```sh
11+
mkdir simple-build-size-watcher
12+
cd simple-build-size-watcher
13+
yarn init -y
14+
```
15+
16+
Let's install codechecks client.
17+
18+
```
19+
yarn add --dev @codechecks/client
20+
```
21+
22+
Let's start developing index.js file. Our check is just a function that takes a path to a file that
23+
we want to observe and it a default export of a module.
24+
25+
```js
26+
const { codechecks } = require("@codechecks/client");
27+
28+
module.exports = function(path) {
29+
// it's alive!
30+
};
31+
```
32+
33+
Lets calculate size of a file pointed by a path. After quick visit at stackoverflow we can come up
34+
with a function getSize:
35+
36+
```js
37+
const fs = require("fs");
38+
function getSize(path) {
39+
const stats = fs.statSync(path);
40+
return stats.size;
41+
}
42+
```
43+
44+
Since we want to track how this value changes in time we need to upload it to StorageAPI. Client
45+
makes this super simple:
46+
47+
```js
48+
const { codechecks } = require("@codechecks/client");
49+
50+
module.exports = function(path) {
51+
const currentSize = getSize(path);
52+
await codechecks.saveValue("simple-build-size-watcher", currentSize);
53+
};
54+
```
55+
56+
`saveValue` takes two arguments: unique name of a value and any value. Saving data to storage api is
57+
automatically prefixed with **current SHA** (opposed to reading).
58+
59+
Yay, we are half way through. Now we need to get previous build size and compare two values.
60+
Remember that value for base branch may not exist, then we just assume it's 0. Nothing simpler:
61+
62+
```js
63+
const { codechecks } = require("@codechecks/client");
64+
const bytes = require("bytes");
65+
66+
module.exports = async function(path) {
67+
const currentSize = getSize(path);
68+
await codechecks.saveValue("simple-build-size-watcher", currentSize);
69+
70+
const baseSize = (await codechecks.getValue("simple-build-size-watcher")) || 0;
71+
72+
const diff = currentSize - baseSize; // ex. 1231
73+
const formattedBytes = bytes(diff); // "1KB"
74+
};
75+
```
76+
77+
Note how we can use existing packages to easily nicely format bytes into something readable. Now the
78+
very last thing that we need to do is report data back to github. We use report api for that.
79+
80+
```js
81+
const { codechecks } = require("@codechecks/client");
82+
const bytes = require("bytes");
83+
84+
module.exports = async function({ path }) {
85+
const currentSize = getSize(path);
86+
await codechecks.saveValue("simple-build-size-watcher", currentSize);
87+
88+
const baseSize = (await codechecks.getValue("simple-build-size-watcher")) || 0;
89+
90+
const diff = currentSize - baseSize; // ex. 1231
91+
const formattedBytes = bytes(diff); // "1KB"
92+
93+
await codechecks.success({
94+
name: "Simple Build Size",
95+
shortDescription: `Size changed by: ${formattedBytes} Total size: ${bytes(currentSize)}`,
96+
});
97+
};
98+
99+
const fs = require("fs");
100+
function getSize(path) {
101+
const stats = fs.statSync(path);
102+
return stats.size;
103+
}
104+
```
105+
106+
That's it. Whole code is placed in `/example` directory of this repo.
107+
108+
## Testing
109+
110+
Because codechecks client is an external dependency that is supposed to be imported by your modules
111+
this makes testing a little bit harder. We recommend to use jest mocking super powers. Tests for
112+
this project are part of `/example` dir.
113+
114+
You can find more complicated example here:
115+
https://github.com/codechecks/build-size-watcher/tree/master/src/__tests__

example/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
lib

example/.prettierignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
.vscode
3+
package.json
4+
lib

example/.prettierrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"printWidth": 100,
3+
"tabWidth": 2,
4+
"semi": true,
5+
"singleQuote": false,
6+
"trailingComma": "all",
7+
"proseWrap": "always"
8+
}

example/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<p align="center">
2+
<h3 align="center">Simple build size watcher</h3>
3+
</p>
4+
5+
## Install
6+
7+
```sh
8+
npm add --save-dev simple-build-size-watcher
9+
```
10+
11+
or
12+
13+
```sh
14+
yarn add --dev simple-build-size-watcher
15+
```
16+
17+
## Usage
18+
19+
Add to your `codechecks.json` file:
20+
21+
<!-- prettier-ignore -->
22+
```json5
23+
{
24+
"checks": [
25+
{
26+
"name": "simple-build-size-watcher",
27+
"options": {
28+
"path": "./index.js"
29+
}
30+
}
31+
32+
// ...
33+
]
34+
}
35+
```
36+
37+
With each pull request you will get information how does build size change over time.
38+
39+
## Licence
40+
41+
MIT @ [codechecks.io](https://codechecks.io)

example/jest.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
roots: ["<rootDir>/src"],
3+
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$",
4+
moduleFileExtensions: ["js", "jsx", "json", "node"],
5+
};

example/package.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "@codechecks/commit-deployment",
3+
"description": "Ship every code change that you make",
4+
"keywords": [
5+
"commit-deploy",
6+
"deployment",
7+
"continuous deployment",
8+
"codechecks"
9+
],
10+
"repository": "codechecks/commit-deployment",
11+
"author": "Chris Kaczor <[email protected]>",
12+
"version": "0.0.4",
13+
"main": "lib/index.js",
14+
"types": "lib/index.d.ts",
15+
"license": "MIT",
16+
"scripts": {
17+
"build": "rm -rf ./lib && tsc",
18+
"format": "prettier --list-different '**/*.{ts,json,md, gql}'",
19+
"format:fix": "prettier --write '**/*.{ts,json,md,gql}'",
20+
"lint": "yarn format",
21+
"lint:fix": "yarn format:fix",
22+
"test:unit": "jest",
23+
"test:watch": "jest --watch",
24+
"test": "yarn lint && yarn test:unit",
25+
"test:fix": "yarn lint:fix && yarn test:unit",
26+
"prepublishOnly": "yarn test && yarn build"
27+
},
28+
"files": [
29+
"lib/**/*"
30+
],
31+
"devDependencies": {
32+
"@codechecks/client": "^0.0.52",
33+
"jest": "^23.6.0",
34+
"mock-fs": "^4.8.0",
35+
"prettier": "^1.15.3"
36+
},
37+
"peerDependencies": {
38+
"@codechecks/client": "^0.0.48"
39+
},
40+
"dependencies": {
41+
"bytes": "^3.1.0"
42+
},
43+
"publishConfig": {
44+
"access": "public"
45+
},
46+
"engines": {
47+
"node": ">=6"
48+
}
49+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports.codechecks = {
2+
report: jest.fn(),
3+
getValue: jest.fn(),
4+
saveValue: jest.fn(),
5+
getCollection: jest.fn(),
6+
saveCollection: jest.fn(),
7+
isPr: jest.fn(),
8+
context: {
9+
workspaceRoot: "/codechecks",
10+
},
11+
getArtifactLink: jest.fn(),
12+
getPageLink: jest.fn(),
13+
success: jest.fn(),
14+
failure: jest.fn(),
15+
};

example/src/__tests__/index.spec.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const { join } = require("path");
2+
const mockFS = require("mock-fs");
3+
4+
const simpleBuildSizeWatcher = require("../index");
5+
const { codechecks } = require("@codechecks/client");
6+
7+
describe("simple-build-size-watcher", () => {
8+
const codeChecksMock = require("../__mocks__/@codechecks/client").codechecks;
9+
beforeEach(() => jest.resetAllMocks());
10+
11+
it("should work", async () => {
12+
codeChecksMock.isPr.mockReturnValue(true);
13+
mockFS({
14+
[join(__dirname, "../build")]: {
15+
"main.js": "APP JS",
16+
},
17+
});
18+
19+
await simpleBuildSizeWatcher({
20+
path: join(__dirname, "../build/main.js"),
21+
});
22+
23+
mockFS.restore();
24+
expect(codechecks.saveValue).toMatchInlineSnapshot(`
25+
[MockFunction] {
26+
"calls": Array [
27+
Array [
28+
"simple-build-size-watcher",
29+
6,
30+
],
31+
],
32+
"results": Array [
33+
Object {
34+
"isThrow": false,
35+
"value": undefined,
36+
},
37+
],
38+
}
39+
`);
40+
41+
expect(codechecks.success).toMatchInlineSnapshot(`
42+
[MockFunction] {
43+
"calls": Array [
44+
Array [
45+
Object {
46+
"name": "Simple Build Size",
47+
"shortDescription": "Size changed by: 6B Total size: 6B",
48+
},
49+
],
50+
],
51+
"results": Array [
52+
Object {
53+
"isThrow": false,
54+
"value": undefined,
55+
},
56+
],
57+
}
58+
`);
59+
});
60+
});

example/src/index.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const { codechecks } = require("@codechecks/client");
2+
const bytes = require("bytes");
3+
4+
module.exports = async function({ path }) {
5+
const currentSize = getSize(path);
6+
await codechecks.saveValue("simple-build-size-watcher", currentSize);
7+
8+
const baseSize = await codechecks.getValue("simple-build-size-watcher") || 0;
9+
10+
const diff = currentSize - baseSize; // ex. 1231
11+
const formattedBytes = bytes(diff); // "1KB"
12+
13+
await codechecks.success({
14+
name: "Simple Build Size",
15+
shortDescription: `Size changed by: ${formattedBytes} Total size: ${bytes(currentSize)}`,
16+
});
17+
};
18+
19+
const fs = require("fs");
20+
function getSize(path) {
21+
const stats = fs.statSync(path);
22+
return stats.size;
23+
}

0 commit comments

Comments
 (0)