diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8eeb714c..db9679c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -177,3 +177,54 @@ jobs: with: name: coverage-lambda-edge path: coverage/ + + perf-measures-type-check-on-pr: + runs-on: ubuntu-latest + permissions: + contents: 'read' + pull-requests: 'write' + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v1 + - run: bun install + - uses: actions/cache/restore@v4 + with: + path: perf-measures/type-check/previous-result.txt + restore-keys: | + type-check-perf-previous-result- + key: type-check-perf-previous-result- + - run: bun scripts/generate-app.ts + working-directory: perf-measures/type-check + - run: bun tsc -p tsconfig.build.json --diagnostics > result.txt + working-directory: perf-measures/type-check + - run: | + { + echo 'COMPARISON<> "$GITHUB_ENV" + working-directory: perf-measures/type-check + - run: echo "$COMPARISON" + # remove the comment out after we make sure that caching is working + # - uses: thollander/actions-comment-pull-request@v2 + # with: + # comment_tag: perf-measures/type-check + # message: ${{ env.COMPARISON }} + + + perf-measures-type-check-on-main: + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v1 + - run: bun install + - run: bun scripts/generate-app.ts + working-directory: perf-measures/type-check + - run: bun tsc -p tsconfig.build.json --diagnostics > previous-result.txt + working-directory: perf-measures/type-check + - uses: actions/cache/save@v4 + with: + path: perf-measures/type-check/previous-result.txt + key: type-check-perf-previous-result-${{ github.sha }} diff --git a/perf-measures/tsconfig.json b/perf-measures/tsconfig.json new file mode 100644 index 00000000..85f8566b --- /dev/null +++ b/perf-measures/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "module": "esnext", + "noEmit": true, + "rootDir": "..", + "strict": true + }, + "include": [ + "**/*.ts", + "**/*.tsx" + ] +} diff --git a/perf-measures/type-check/.gitignore b/perf-measures/type-check/.gitignore new file mode 100644 index 00000000..79bd69e2 --- /dev/null +++ b/perf-measures/type-check/.gitignore @@ -0,0 +1,4 @@ +generated +!generated/.gitkeep +trace +*result.txt diff --git a/perf-measures/type-check/client.ts b/perf-measures/type-check/client.ts new file mode 100644 index 00000000..022a5bef --- /dev/null +++ b/perf-measures/type-check/client.ts @@ -0,0 +1,4 @@ +import type { app } from './generated/app' +import { hc } from '../../src/client' + +const client = hc('/') diff --git a/perf-measures/type-check/generated/.gitkeep b/perf-measures/type-check/generated/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/perf-measures/type-check/scripts/generate-app.ts b/perf-measures/type-check/scripts/generate-app.ts new file mode 100644 index 00000000..669601df --- /dev/null +++ b/perf-measures/type-check/scripts/generate-app.ts @@ -0,0 +1,25 @@ +import { writeFile } from 'node:fs' +import * as path from 'node:path' + +const count = 200 + +const generateRoutes = (count: number) => { + let routes = `import { Hono } from '../../../src' +export const app = new Hono()` + for (let i = 1; i <= count; i++) { + routes += ` + .get('/route${i}/:id', (c) => { + return c.json({ + ok: true + }) + })` + } + return routes +} + +const routes = generateRoutes(count) + +writeFile(path.join(import.meta.dirname, '../generated/app.ts'), routes, (err) => { + if (err) { throw err } + console.log(`${count} routes have been written to app.ts`) +}) diff --git a/perf-measures/type-check/scripts/process-results.ts b/perf-measures/type-check/scripts/process-results.ts new file mode 100644 index 00000000..b1d10ec3 --- /dev/null +++ b/perf-measures/type-check/scripts/process-results.ts @@ -0,0 +1,18 @@ +import * as fs from 'node:fs/promises' + +async function main() { + const currentResult = (await fs.readFile('./result.txt')).toString().split('\n') + const previousResult = await fs.readFile('./previous-result.txt') + .then((data) => data.toString().split('\n')) + .catch(() => null) + const table = ['|| Current | Previous |', '|---|---|---|'] + for (const [i, line] of currentResult.entries()) { + if (line === '') {continue} + const [name, value] = line.split(':') + const mainValue = previousResult?.[i]?.split(':')?.[1] + table.push(`| ${name?.trim()} | ${value?.trim()} | ${mainValue ? mainValue.trim() : 'N/A'} |`) + } + console.log(table.join('\n')) +} + +main() diff --git a/perf-measures/type-check/tsconfig.build.json b/perf-measures/type-check/tsconfig.build.json new file mode 100644 index 00000000..1dd95f84 --- /dev/null +++ b/perf-measures/type-check/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "../tsconfig.json", + "include": ["client.ts"] +} diff --git a/vitest.config.ts b/vitest.config.ts index 8c968fde..27da5b9d 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -22,6 +22,7 @@ export default defineConfig({ 'runtime-tests', 'build.ts', 'src/test-utils', + 'perf-measures', // types are compile-time only, so their coverage cannot be measured 'src/**/types.ts',