From c14a3f99a3aef3bd552353cbd735fa7aabd55b89 Mon Sep 17 00:00:00 2001 From: Wojciech Maj Date: Mon, 2 Feb 2026 16:32:47 +0100 Subject: [PATCH 1/2] chore: run lint without installing the repo --- .github/workflows/ci.yml | 8 ++------ scripts/lint.ts | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 scripts/lint.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c77557dae..a4a11684d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,14 +32,10 @@ jobs: - uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c name: Install pnpm - with: - cache: true - - - name: 📦 Install dependencies - run: pnpm install + # pnpm cache skipped deliberately as the project is not actually installed here - name: 🔠 Lint project - run: pnpm lint + run: node scripts/lint.ts test: runs-on: ubuntu-latest diff --git a/scripts/lint.ts b/scripts/lint.ts new file mode 100644 index 000000000..2c217f1f0 --- /dev/null +++ b/scripts/lint.ts @@ -0,0 +1,39 @@ +/** + * This script runs oxlint and oxfmt in a CI environment, without the need to install the entire + * project. It reads the required version from pnpm-lock.yaml and executes the linters accordingly. + * It's "stupid by design" so it could work in minimal Node.js environments. + */ + +import { spawnSync } from 'node:child_process' +import { readFileSync } from 'node:fs' + +const lockfileContent = readFileSync('pnpm-lock.yaml', 'utf8') +const lines = lockfileContent.split(/\n/) + +function getDependencyVersion(dependencyName: string): string { + const versionRegex = new RegExp(`^\\s+${dependencyName}@([^\\s]+):`) + + for (let index = 0; index < lines.length; index += 1) { + const match = lines[index].match(versionRegex) + + if (match) { + return match[1] + } + } + + throw new Error(`Could not resolve ${dependencyName} version from pnpm-lock.yaml.`) +} + +const oxlintVersion = getDependencyVersion('oxlint') +const oxfmtVersion = getDependencyVersion('oxfmt') + +function runCommand(command: string, args: string[]) { + const result = spawnSync(command, args, { stdio: 'inherit' }) + + if (result.status) { + process.exit(result.status) + } +} + +runCommand('pnpx', [`oxlint@${oxlintVersion}`]) +runCommand('pnpx', [`oxfmt@${oxfmtVersion}`, '--check']) From 62765f2c2008ea66a6ac18e01521742b2101cc0e Mon Sep 17 00:00:00 2001 From: Wojciech Maj Date: Tue, 3 Feb 2026 09:19:23 +0100 Subject: [PATCH 2/2] chore: run knip without installing the repo --- .github/workflows/ci.yml | 10 +++------- scripts/knip.ts | 11 +++++++++++ scripts/lint.ts | 24 +----------------------- scripts/utils.ts | 27 +++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 30 deletions(-) create mode 100644 scripts/knip.ts create mode 100644 scripts/utils.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4a11684d..4c0709dcb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,11 +128,7 @@ jobs: - uses: pnpm/action-setup@1e1c8eafbd745f64b1ef30a7d7ed7965034c486c name: Install pnpm - with: - cache: true - - - name: 📦 Install dependencies - run: pnpm install + # pnpm cache skipped deliberately as the project is not actually installed here - - name: 🔍 Check for unused code - run: pnpm knip + - name: 🔠 Lint project + run: node scripts/knip.ts diff --git a/scripts/knip.ts b/scripts/knip.ts new file mode 100644 index 000000000..f82b2fbc9 --- /dev/null +++ b/scripts/knip.ts @@ -0,0 +1,11 @@ +/** + * This script runs knip in a CI environment, without the need to install the entire project. It + * reads the required version from pnpm-lock.yaml and executes the linter accordingly. It's "stupid + * by design" so it could work in minimal Node.js environments. + */ + +import { getDependencyVersion, runCommand } from './utils.ts' + +const knipVersion = getDependencyVersion('knip') + +runCommand('pnpx', [`knip@${knipVersion}`]) diff --git a/scripts/lint.ts b/scripts/lint.ts index 2c217f1f0..967fe5416 100644 --- a/scripts/lint.ts +++ b/scripts/lint.ts @@ -4,36 +4,14 @@ * It's "stupid by design" so it could work in minimal Node.js environments. */ -import { spawnSync } from 'node:child_process' import { readFileSync } from 'node:fs' +import { getDependencyVersion, runCommand } from './utils.ts' const lockfileContent = readFileSync('pnpm-lock.yaml', 'utf8') const lines = lockfileContent.split(/\n/) -function getDependencyVersion(dependencyName: string): string { - const versionRegex = new RegExp(`^\\s+${dependencyName}@([^\\s]+):`) - - for (let index = 0; index < lines.length; index += 1) { - const match = lines[index].match(versionRegex) - - if (match) { - return match[1] - } - } - - throw new Error(`Could not resolve ${dependencyName} version from pnpm-lock.yaml.`) -} - const oxlintVersion = getDependencyVersion('oxlint') const oxfmtVersion = getDependencyVersion('oxfmt') -function runCommand(command: string, args: string[]) { - const result = spawnSync(command, args, { stdio: 'inherit' }) - - if (result.status) { - process.exit(result.status) - } -} - runCommand('pnpx', [`oxlint@${oxlintVersion}`]) runCommand('pnpx', [`oxfmt@${oxfmtVersion}`, '--check']) diff --git a/scripts/utils.ts b/scripts/utils.ts new file mode 100644 index 000000000..2c02f682d --- /dev/null +++ b/scripts/utils.ts @@ -0,0 +1,27 @@ +import { spawnSync } from 'node:child_process' +import { readFileSync } from 'node:fs' + +const lockfileContent = readFileSync('pnpm-lock.yaml', 'utf8') +const lines = lockfileContent.split(/\n/) + +export function getDependencyVersion(dependencyName: string): string { + const versionRegex = new RegExp(`^\\s+${dependencyName}@([^\\s]+):`) + + for (let index = 0; index < lines.length; index += 1) { + const match = lines[index].match(versionRegex) + + if (match) { + return match[1] + } + } + + throw new Error(`Could not resolve ${dependencyName} version from pnpm-lock.yaml.`) +} + +export function runCommand(command: string, args: string[]) { + const result = spawnSync(command, args, { stdio: 'inherit' }) + + if (result.status) { + process.exit(result.status) + } +}