From 2dbe46f086759ca4f3b6972531c6a9e7c1772d81 Mon Sep 17 00:00:00 2001 From: AsPulse <84216737+AsPulse@users.noreply.github.com> Date: Sun, 5 Mar 2023 23:09:31 +0900 Subject: [PATCH] [chore] eslint, jest CI (#5) * ESLint GitHub Actions * Fix Directory Name workflow to workflows * Fix yarn does not install dependencies * Fix filter_mode * Test for ESLint CI * Reporter pr-review to pr-check * Fix permission * Revert "Test for ESLint CI" This reverts commit daf968c859473ce2638385ad52efdf0194d5ba4c. * Create test.yml * Create bundle-size-diff tools * Remove name * Fix over-jobs variable * Fix Comment Settings * Create Auto Approve Actions * Fix Conditions --- .eslintrc.cjs | 7 +- .github/workflows/auto-approve.yml | 11 +++ .github/workflows/bundle-size.yml | 79 ++++++++++++++++ .github/workflows/lint.yml | 26 ++++++ .github/workflows/test.yml | 21 +++++ misc/bundle-size-diff.ts | 119 ++++++++++++++++++++++++ package.json | 1 + tsconfig.json | 9 +- yarn.lock | 139 ++++++++++++++++++++++++++++- 9 files changed, 404 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/auto-approve.yml create mode 100644 .github/workflows/bundle-size.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test.yml create mode 100644 misc/bundle-size-diff.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 5820f74..8221a68 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -56,7 +56,7 @@ module.exports = { 'function-call-argument-newline': [ 'error', 'consistent' ], 'dot-location': [ 'error', 'property' ], 'dot-notation': [ 'error' ], - '@typescript-eslint/array-type': [ 'error', 'array-simple' ], + '@typescript-eslint/array-type': [ 'error', { default: 'array-simple', readonly: 'array-simple' }], '@typescript-eslint/prefer-for-of': [ 'error' ], '@typescript-eslint/prefer-includes': [ 'error' ], @@ -100,10 +100,10 @@ module.exports = { 'unused-imports/no-unused-imports': [ 'error' ], /* Maintainability */ - 'complexity': [ 'warn', 6 ], + 'complexity': [ 'warn', 10 ], 'max-classes-per-file': [ 'warn', 1 ], 'max-depth': [ 'warn', 3 ], - 'max-len': [ 'warn', { code: 50, ignoreComments: true, ignoreStrings: true, ignoreTemplateLiterals: true }], + 'max-len': [ 'warn', { code: 100, ignoreComments: true, ignoreStrings: true, ignoreTemplateLiterals: true }], 'max-lines-per-function': [ 'warn', 50 ], 'no-multi-str': [ 'warn' ], 'object-shorthand': [ 'warn' ], @@ -123,7 +123,6 @@ module.exports = { 'no-self-compare': [ 'error' ], 'no-unmodified-loop-condition': [ 'error' ], 'no-unused-private-class-members': [ 'error' ], - 'no-use-before-define': [ 'error' ], 'no-param-reassign': [ 'error' ], 'no-return-assign': [ 'error' ], 'no-return-await': [ 'error' ], diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml new file mode 100644 index 0000000..45e9cdb --- /dev/null +++ b/.github/workflows/auto-approve.yml @@ -0,0 +1,11 @@ +name: auto-approve +on: [pull_request] + +jobs: + auto-approve: + runs-on: ubuntu-latest + permissions: + pull-requests: write + if: github.event.pull_request.user.login == 'AsPulse' + steps: + - uses: hmarr/auto-approve-action@v3 diff --git a/.github/workflows/bundle-size.yml b/.github/workflows/bundle-size.yml new file mode 100644 index 0000000..def9f0e --- /dev/null +++ b/.github/workflows/bundle-size.yml @@ -0,0 +1,79 @@ +name: bundle-size +on: [pull_request] + +jobs: + build_head: + runs-on: [ubuntu-latest] + permissions: + contents: read + outputs: + result: ${{ steps.export.outputs.HEAD_RESULT }} + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'yarn' + - name: Install Dependencies + run: yarn install --immutable + - name: Build + run: yarn build + - name: Export Size Info + id: export + run: | + echo "HEAD_RESULT=$(yarn ts-node ./misc/bundle-size-diff.ts inspect)" >> $GITHUB_OUTPUT + + build_base: + runs-on: [ubuntu-latest] + permissions: + contents: read + outputs: + result: ${{ steps.export.outputs.BASE_RESULT }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ github.base_re }} + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'yarn' + - name: Install Dependencies + run: yarn install --immutable + - name: Build + run: yarn build + - name: Export Size Info + id: export + run: | + echo "BASE_RESULT=$(yarn ts-node ./misc/bundle-size-diff.ts inspect)" >> $GITHUB_OUTPUT + + compare: + runs-on: [ubuntu-latest] + needs: [build_base, build_head] + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ github.base_re }} + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'yarn' + - name: Install Dependencies + run: yarn install --immutable + - name: Export Markdown + env: + HEAD_RESULT: ${{ needs.build_head.outputs.result }} + BASE_RESULT: ${{ needs.build_base.outputs.result }} + run: yarn ts-node ./misc/bundle-size-diff.ts diff $HEAD_RESULT $BASE_RESULT + - name: Post Review Comment + uses: mshick/add-pr-comment@v2 + with: + message-path: 'bundle-size/result.md' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..f85578f --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,26 @@ +name: lint +on: [pull_request] + +jobs: + eslint: + runs-on: [ubuntu-latest] + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'yarn' + - name: Install Dependencies + run: yarn install --immutable + - name: Run ESLint + uses: reviewdog/action-eslint@v1 + with: + github_token: ${{ secrets.github_token }} + reporter: github-pr-review + filter_mode: diff_context + fail_on_error: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..f56e108 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,21 @@ +name: test +on: [pull_request] + +jobs: + jest: + runs-on: [ubuntu-latest] + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'yarn' + - name: Install Dependencies + run: yarn install --immutable + - name: Run Jest + run: yarn test diff --git a/misc/bundle-size-diff.ts b/misc/bundle-size-diff.ts new file mode 100644 index 0000000..8813056 --- /dev/null +++ b/misc/bundle-size-diff.ts @@ -0,0 +1,119 @@ +/* eslint-disable no-console */ +import { rm, mkdir, readFile, writeFile } from 'fs/promises'; + +interface Diff { + head: number; + base: number; + diff: number; +} + +interface DiffResult { + cjs: Diff; + esm: Diff; + package: Diff; +} + +function getDiff(args: string[]): DiffResult { + + const size = { head: args[3], base: args[4] }; + if (size.head === undefined || size.base === undefined) { + console.error('Usage: bundle-size-diff diff '); + process.exit(1); + } + + const [ headCjs, headEsm, headPackage ] = size.head.split(':').map(v => parseInt(v, 10)); + const [ baseCjs, baseEsm, basePackage ] = size.base.split(':').map(v => parseInt(v, 10)); + if ( + headCjs === undefined || headEsm === undefined || headPackage === undefined || + baseCjs === undefined || baseEsm === undefined || basePackage === undefined + ) { + console.error('Error: invalid size format.'); + process.exit(1); + } + + return { + cjs: { head: headCjs, base: baseCjs, diff: headCjs - baseCjs }, + esm: { head: headEsm, base: baseEsm, diff: headEsm - baseEsm }, + package: { head: headPackage, base: basePackage, diff: headPackage - basePackage }, + }; + +} + +async function exportToMarkdown(data: DiffResult): Promise { + const result = [ + '## Bundle Size Summary', + '||Base branch|HEAD branch|Diff|', + '|--:|:--:|:--:|:--:|', + [ + '', + 'CommonJS', + formatSize(data.cjs.base), formatSize(data.cjs.head), + `**${getSymbol(data.cjs.diff)} ${formatSize(Math.abs(data.cjs.diff))}**`, + '', + ].join('|'), + [ + '', + 'ES Module', + formatSize(data.esm.base), formatSize(data.esm.head), + `**${getSymbol(data.esm.diff)} ${formatSize(Math.abs(data.esm.diff))}**`, + '', + ].join('|'), + [ + '', + 'Package', + formatSize(data.package.base), formatSize(data.package.head), + `**${getSymbol(data.package.diff)} ${formatSize(Math.abs(data.package.diff))}**`, + '', + ].join('|'), + ].join('\n'); + await rm('./bundle-size', { recursive: true, force: true }); + await mkdir('./bundle-size', { recursive: true }); + await writeFile('./bundle-size/result.md', result); + console.log('Result is exported to: bundle-size/result.md'); + return; +} + +export function getSymbol(diff: number): string { + return diff === 0 ? '+/-' : diff < 0 ? '-' : '+'; +} +export function formatSize(byte: number): string { + return `${Math.round(byte / 10) / 100} kB`; +} + +async function main(): Promise { + const args = process.argv; + switch (args[2]) { + case 'inspect': + try { + const cjs = await readFile('./dist/cjs/index.js'); + const esm = await readFile('./dist/esm/index.js'); + const cjsDts = await readFile('./dist/cjs/index.d.ts'); + const esmDts = await readFile('./dist/esm/index.d.ts'); + const packageJson = await readFile('./package.json'); + const license = await readFile('./LICENSE'); + const readme = await readFile('./README.md'); + console.log([ + cjs.byteLength, + esm.byteLength, + [ cjs, esm, cjsDts, esmDts, packageJson, license, readme ] + .map(v => v.byteLength) + .reduce((a, b) => a + b, 0), + ].join(':')); + } catch { + console.error('Error: some of build artifacts not found.'); + process.exit(1); + } + break; + + case 'diff': + await exportToMarkdown( getDiff(args) ); + break; + + default: + console.error('Usage: bundle-size-diff [inspect|diff]'); + process.exit(1); + } +} + + +void main(); diff --git a/package.json b/package.json index b7bdbb0..acbd81d 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "rollup": "^3.18.0", "rollup-plugin-dts": "^5.2.0", "rollup-plugin-swc3": "^0.8.0", + "ts-node": "^10.9.1", "tslib": "^2.5.0", "typescript": "^4.9.5" }, diff --git a/tsconfig.json b/tsconfig.json index c15d8ca..7f7d093 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,6 +27,11 @@ "noFallthroughCasesInSwitch": true, "noUncheckedIndexedAccess": true }, - "include": ["src", "tests", ".eslintrc.cjs", "rollup.config.mjs", "jest.config.cjs"], - "exclude": ["node_modules", "dist"] + "include": ["src", "tests", "misc", ".eslintrc.cjs", "rollup.config.mjs", "jest.config.cjs"], + "exclude": ["node_modules", "dist"], + "ts-node": { + "compilerOptions": { + "module": "commonjs" + } + } } diff --git a/yarn.lock b/yarn.lock index acd8ae1..f471dbd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -410,6 +410,15 @@ __metadata: languageName: node linkType: hard +"@cspotcode/source-map-support@npm:^0.8.0": + version: 0.8.1 + resolution: "@cspotcode/source-map-support@npm:0.8.1" + dependencies: + "@jridgewell/trace-mapping": 0.3.9 + checksum: 5718f267085ed8edb3e7ef210137241775e607ee18b77d95aa5bd7514f47f5019aa2d82d96b3bf342ef7aa890a346fa1044532ff7cc3009e7d24fce3ce6200fa + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^2.0.0": version: 2.0.0 resolution: "@eslint/eslintrc@npm:2.0.0" @@ -766,7 +775,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/resolve-uri@npm:3.1.0": +"@jridgewell/resolve-uri@npm:3.1.0, @jridgewell/resolve-uri@npm:^3.0.3": version: 3.1.0 resolution: "@jridgewell/resolve-uri@npm:3.1.0" checksum: b5ceaaf9a110fcb2780d1d8f8d4a0bfd216702f31c988d8042e5f8fbe353c55d9b0f55a1733afdc64806f8e79c485d2464680ac48a0d9fcadb9548ee6b81d267 @@ -787,6 +796,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" + dependencies: + "@jridgewell/resolve-uri": ^3.0.3 + "@jridgewell/sourcemap-codec": ^1.4.10 + checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.15, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.17 resolution: "@jridgewell/trace-mapping@npm:0.3.17" @@ -936,6 +955,7 @@ __metadata: rollup: ^3.18.0 rollup-plugin-dts: ^5.2.0 rollup-plugin-swc3: ^0.8.0 + ts-node: ^10.9.1 tslib: ^2.5.0 typescript: ^4.9.5 peerDependencies: @@ -1076,6 +1096,34 @@ __metadata: languageName: node linkType: hard +"@tsconfig/node10@npm:^1.0.7": + version: 1.0.9 + resolution: "@tsconfig/node10@npm:1.0.9" + checksum: a33ae4dc2a621c0678ac8ac4bceb8e512ae75dac65417a2ad9b022d9b5411e863c4c198b6ba9ef659e14b9fb609bbec680841a2e84c1172df7a5ffcf076539df + languageName: node + linkType: hard + +"@tsconfig/node12@npm:^1.0.7": + version: 1.0.11 + resolution: "@tsconfig/node12@npm:1.0.11" + checksum: 5ce29a41b13e7897a58b8e2df11269c5395999e588b9a467386f99d1d26f6c77d1af2719e407621412520ea30517d718d5192a32403b8dfcc163bf33e40a338a + languageName: node + linkType: hard + +"@tsconfig/node14@npm:^1.0.0": + version: 1.0.3 + resolution: "@tsconfig/node14@npm:1.0.3" + checksum: 19275fe80c4c8d0ad0abed6a96dbf00642e88b220b090418609c4376e1cef81bf16237bf170ad1b341452feddb8115d8dd2e5acdfdea1b27422071163dc9ba9d + languageName: node + linkType: hard + +"@tsconfig/node16@npm:^1.0.2": + version: 1.0.3 + resolution: "@tsconfig/node16@npm:1.0.3" + checksum: 3a8b657dd047495b7ad23437d6afd20297ce90380ff0bdee93fc7d39a900dbd8d9e26e53ff6b465e7967ce2adf0b218782590ce9013285121e6a5928fbd6819f + languageName: node + linkType: hard + "@types/babel__core@npm:^7.1.14": version: 7.20.0 resolution: "@types/babel__core@npm:7.20.0" @@ -1397,7 +1445,14 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.8.0": +"acorn-walk@npm:^8.1.1": + version: 8.2.0 + resolution: "acorn-walk@npm:8.2.0" + checksum: 1715e76c01dd7b2d4ca472f9c58968516a4899378a63ad5b6c2d668bba8da21a71976c14ec5f5b75f887b6317c4ae0b897ab141c831d741dc76024d8745f1ad1 + languageName: node + linkType: hard + +"acorn@npm:^8.4.1, acorn@npm:^8.8.0": version: 8.8.2 resolution: "acorn@npm:8.8.2" bin: @@ -1516,6 +1571,13 @@ __metadata: languageName: node linkType: hard +"arg@npm:^4.1.0": + version: 4.1.3 + resolution: "arg@npm:4.1.3" + checksum: 544af8dd3f60546d3e4aff084d451b96961d2267d668670199692f8d054f0415d86fc5497d0e641e91546f0aa920e7c29e5250e99fc89f5552a34b5d93b77f43 + languageName: node + linkType: hard + "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10" @@ -1958,6 +2020,13 @@ __metadata: languageName: node linkType: hard +"create-require@npm:^1.1.0": + version: 1.1.1 + resolution: "create-require@npm:1.1.1" + checksum: a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -2056,6 +2125,13 @@ __metadata: languageName: node linkType: hard +"diff@npm:^4.0.1": + version: 4.0.2 + resolution: "diff@npm:4.0.2" + checksum: f2c09b0ce4e6b301c221addd83bf3f454c0bc00caa3dd837cf6c127d6edf7223aa2bbe3b688feea110b7f262adbfc845b757c44c8a9f8c0c5b15d8fa9ce9d20d + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -4045,6 +4121,13 @@ __metadata: languageName: node linkType: hard +"make-error@npm:^1.1.1": + version: 1.3.6 + resolution: "make-error@npm:1.3.6" + checksum: b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 + languageName: node + linkType: hard + "make-fetch-happen@npm:^10.0.3": version: 10.2.1 resolution: "make-fetch-happen@npm:10.2.1" @@ -5248,6 +5331,44 @@ __metadata: languageName: node linkType: hard +"ts-node@npm:^10.9.1": + version: 10.9.1 + resolution: "ts-node@npm:10.9.1" + dependencies: + "@cspotcode/source-map-support": ^0.8.0 + "@tsconfig/node10": ^1.0.7 + "@tsconfig/node12": ^1.0.7 + "@tsconfig/node14": ^1.0.0 + "@tsconfig/node16": ^1.0.2 + acorn: ^8.4.1 + acorn-walk: ^8.1.1 + arg: ^4.1.0 + create-require: ^1.1.0 + diff: ^4.0.1 + make-error: ^1.1.1 + v8-compile-cache-lib: ^3.0.1 + yn: 3.1.1 + peerDependencies: + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" + peerDependenciesMeta: + "@swc/core": + optional: true + "@swc/wasm": + optional: true + bin: + ts-node: dist/bin.js + ts-node-cwd: dist/bin-cwd.js + ts-node-esm: dist/bin-esm.js + ts-node-script: dist/bin-script.js + ts-node-transpile-only: dist/bin-transpile.js + ts-script: dist/bin-script-deprecated.js + checksum: 090adff1302ab20bd3486e6b4799e90f97726ed39e02b39e566f8ab674fd5bd5f727f43615debbfc580d33c6d9d1c6b1b3ce7d8e3cca3e20530a145ffa232c35 + languageName: node + linkType: hard + "tsconfig-paths@npm:^3.14.1": version: 3.14.2 resolution: "tsconfig-paths@npm:3.14.2" @@ -5406,6 +5527,13 @@ __metadata: languageName: node linkType: hard +"v8-compile-cache-lib@npm:^3.0.1": + version: 3.0.1 + resolution: "v8-compile-cache-lib@npm:3.0.1" + checksum: 78089ad549e21bcdbfca10c08850022b22024cdcc2da9b168bcf5a73a6ed7bf01a9cebb9eac28e03cd23a684d81e0502797e88f3ccd27a32aeab1cfc44c39da0 + languageName: node + linkType: hard + "v8-to-istanbul@npm:^9.0.1": version: 9.1.0 resolution: "v8-to-istanbul@npm:9.1.0" @@ -5551,6 +5679,13 @@ __metadata: languageName: node linkType: hard +"yn@npm:3.1.1": + version: 3.1.1 + resolution: "yn@npm:3.1.1" + checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 + languageName: node + linkType: hard + "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0"