From 57811723d9126e7931f8d9c6e2e6675f171aa9f8 Mon Sep 17 00:00:00 2001 From: Tiberius Silivestru Date: Tue, 9 Dec 2025 20:45:10 -0700 Subject: [PATCH 1/8] initial ci file --- .github/workflows/ci.yml | 54 ++++++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 5 ++-- package-lock.json | 23 +++-------------- package.json | 2 +- 4 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5f4ce72 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,54 @@ +name: CI + +on: + push: + branches: [main, vitest, simplify-build] + pull_request: + branches: [main] + +jobs: + test: + name: Test + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20, 22] + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Type check + run: npm run typecheck + + - name: Lint + run: npm run lint + + - name: Format check + run: npm run format + + - name: Run unit tests + run: npm test + + - name: Build + run: npm run build + + - name: Run integration tests + run: npm run test:integration + + - name: Upload coverage + if: matrix.node-version == 22 + uses: codecov/codecov-action@v4 + with: + files: ./coverage/coverage-final.json + flags: unittests + fail_ci_if_error: false diff --git a/CHANGELOG.md b/CHANGELOG.md index b0f3362..1a4b57b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,11 @@ All notable changes to this project will be documented in this file. - **Postbuild Script**: Replaced `insert-shebang.sh` with lightweight `add-shebang.js` Node script - **CJS Package Generation**: Now generated inline in build script instead of via wrapper - **README**: Updated "How It Works" section to reflect simplified build architecture +- **GitHub Actions**: Added CI workflow for automated testing on Node 20 and 22 ### Technical Details -**Build Process (Simplified):** +Build Process (Simplified): 1. Prebuild: format:fix → lint → typecheck → clean 2. Compile: SWC compiles source to both `build/esm/src/` and `build/cjs/src/` @@ -21,7 +22,7 @@ All notable changes to this project will be documented in this file. 4. Executables: `add-shebang.js` adds shebangs and sets executable permissions 5. CJS Marker: `package.json` with `"type":"commonjs"` created in `build/cjs/` -**Entry Points:** +Entry Points: - ESM: `build/esm/src/cli.js` (executable) - CJS: `build/cjs/src/cli.js` (executable) diff --git a/package-lock.json b/package-lock.json index ea57d4a..8c82794 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "hello-cli", - "version": "0.2.0", + "version": "0.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "hello-cli", - "version": "0.2.0", + "version": "0.3.2", "license": "MIT", "dependencies": { "commander": "^14.0.2" }, "bin": { - "hello-cli": "build/esm/cli.js" + "hello-cli": "build/esm/src/cli.js" }, "devDependencies": { "@biomejs/biome": "2.3.8", @@ -26,7 +26,7 @@ "vitest": "^4.0.15" }, "engines": { - "node": ">=22" + "node": ">=20" } }, "node_modules/@babel/helper-string-parser": { @@ -3975,21 +3975,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", diff --git a/package.json b/package.json index 076e88c..a44098a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hello-cli", - "version": "0.3.1", + "version": "0.3.2", "description": "A basic CLI written in TypeScript meant to be used as an example or project starter", "type": "module", "bin": "./build/esm/src/cli.js", From 937cb872de1fc41764b84f38e00a756771e389b2 Mon Sep 17 00:00:00 2001 From: Tiberius Silivestru Date: Tue, 9 Dec 2025 20:54:20 -0700 Subject: [PATCH 2/8] update ci file --- .github/workflows/ci.yml | 10 +++++++++- package.json | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f4ce72..b4fc54c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,15 @@ jobs: run: npm test - name: Build - run: npm run build + run: npm run build:ci + + - name: Verify build outputs + run: | + test -f build/esm/src/cli.js || (echo "ESM build failed" && exit 1) + test -f build/cjs/src/cli.js || (echo "CJS build failed" && exit 1) + test -x build/esm/src/cli.js || (echo "ESM cli not executable" && exit 1) + test -x build/cjs/src/cli.js || (echo "CJS cli not executable" && exit 1) + echo "✓ Build outputs verified" - name: Run integration tests run: npm run test:integration diff --git a/package.json b/package.json index a44098a..c9b9445 100644 --- a/package.json +++ b/package.json @@ -31,9 +31,10 @@ }, "scripts": { "prebuild": "npm run format:fix && npm run lint && npm run typecheck && rm -rf ./build", - "build:esm": "swc src --config-file .swcrc-esm -d build/esm --ignore '**/*.test.ts' && tsc-alias -p tsconfig.json --outDir build/esm --resolve-full-paths", - "build:cjs": "swc src --config-file .swcrc-cjs -d build/cjs --ignore '**/*.test.ts' && tsc-alias -p tsconfig.json --outDir build/cjs --resolve-full-paths && echo '{\"type\":\"commonjs\"}' > build/cjs/package.json", + "build:esm": "swc src --config-file .swcrc-esm -d build/esm --ignore '**/*.test.ts' && tsc-alias -p tsconfig.json --outDir build/esm --resolve-full-paths || exit 1", + "build:cjs": "swc src --config-file .swcrc-cjs -d build/cjs --ignore '**/*.test.ts' && tsc-alias -p tsconfig.json --outDir build/cjs --resolve-full-paths && echo '{\"type\":\"commonjs\"}' > build/cjs/package.json || exit 1", "build": "npm run build:esm && npm run build:cjs && node ./add-shebang.js", + "build:ci": "rm -rf ./build && npm run build:esm && npm run build:cjs && node ./add-shebang.js", "build:debug": "swc --config-file .swcrc-esm -s true -D src -d build/esm", "typecheck": "tsc --noEmit", "prepublishOnly": "npm run typecheck && npm run lint && npm test && npm run build", From ae65a6608350cc9c50b8b2defddc937480841b92 Mon Sep 17 00:00:00 2001 From: Tiberius Silivestru Date: Tue, 9 Dec 2025 21:00:03 -0700 Subject: [PATCH 3/8] ci integration test script --- .github/workflows/ci.yml | 2 +- package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4fc54c..5def637 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: echo "✓ Build outputs verified" - name: Run integration tests - run: npm run test:integration + run: npm run test:integration:ci - name: Upload coverage if: matrix.node-version == 22 diff --git a/package.json b/package.json index c9b9445..2c930fc 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "lint:fix": "biome lint --write ./src", "test": "vitest run", "test:integration": "npm run build && vitest run tests/integration", + "test:integration:ci": "vitest run tests/integration", "test:all": "npm test && npm run test:integration", "test:cov": "vitest run --coverage" }, From 52b65bd18d188ea6e49f623d7002eb42b6f6fa6c Mon Sep 17 00:00:00 2001 From: Tiberius Silivestru Date: Tue, 9 Dec 2025 21:03:13 -0700 Subject: [PATCH 4/8] update vitest config --- vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vitest.config.ts b/vitest.config.ts index 4fa96e8..0503a7d 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -6,7 +6,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url)); export default defineConfig({ test: { - exclude: ["**/node_modules/**", "**/build/**"], + exclude: ["**/node_modules/**", "**/build/**", "**/tests/integration/**"], coverage: { reporter: ["text", "json", "html"], }, From 4b597639f008367268636f24d6976cccc8ad072c Mon Sep 17 00:00:00 2001 From: Tiberius Silivestru Date: Tue, 9 Dec 2025 21:16:59 -0700 Subject: [PATCH 5/8] code cleanup --- .github/workflows/ci.yml | 21 +++++++++------------ package.json | 4 ++-- vitest.config.integration.ts | 17 +++++++++++++++++ vitest.config.ts | 3 ++- 4 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 vitest.config.integration.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5def637..91ebc56 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,16 +2,21 @@ name: CI on: push: - branches: [main, vitest, simplify-build] + branches: [main] pull_request: branches: [main] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: - name: Test + name: Node ${{ matrix.node-version }} runs-on: ubuntu-latest strategy: + fail-fast: false matrix: node-version: [20, 22] @@ -37,19 +42,11 @@ jobs: run: npm run format - name: Run unit tests - run: npm test + run: npm run test:cov - name: Build run: npm run build:ci - - name: Verify build outputs - run: | - test -f build/esm/src/cli.js || (echo "ESM build failed" && exit 1) - test -f build/cjs/src/cli.js || (echo "CJS build failed" && exit 1) - test -x build/esm/src/cli.js || (echo "ESM cli not executable" && exit 1) - test -x build/cjs/src/cli.js || (echo "CJS cli not executable" && exit 1) - echo "✓ Build outputs verified" - - name: Run integration tests run: npm run test:integration:ci @@ -57,6 +54,6 @@ jobs: if: matrix.node-version == 22 uses: codecov/codecov-action@v4 with: + token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage/coverage-final.json - flags: unittests fail_ci_if_error: false diff --git a/package.json b/package.json index 2c930fc..890eada 100644 --- a/package.json +++ b/package.json @@ -44,8 +44,8 @@ "lint": "biome lint ./src", "lint:fix": "biome lint --write ./src", "test": "vitest run", - "test:integration": "npm run build && vitest run tests/integration", - "test:integration:ci": "vitest run tests/integration", + "test:integration": "npm run build && vitest run --config vitest.config.integration.ts", + "test:integration:ci": "vitest run --config vitest.config.integration.ts", "test:all": "npm test && npm run test:integration", "test:cov": "vitest run --coverage" }, diff --git a/vitest.config.integration.ts b/vitest.config.integration.ts new file mode 100644 index 0000000..1f47c64 --- /dev/null +++ b/vitest.config.integration.ts @@ -0,0 +1,17 @@ +import { fileURLToPath } from "node:url"; +import { dirname, resolve } from "node:path"; +import { defineConfig } from "vitest/config"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineConfig({ + test: { + exclude: ["**/node_modules/**", "**/build/**"], + include: ["tests/integration/**/*.{test,spec}.{js,ts}"], + }, + resolve: { + alias: { + "@": resolve(__dirname, "./src"), + }, + }, +}); diff --git a/vitest.config.ts b/vitest.config.ts index 0503a7d..ef19bf6 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -6,7 +6,8 @@ const __dirname = dirname(fileURLToPath(import.meta.url)); export default defineConfig({ test: { - exclude: ["**/node_modules/**", "**/build/**", "**/tests/integration/**"], + exclude: ["**/node_modules/**", "**/build/**"], + include: ["src/**/*.{test,spec}.{js,ts}"], coverage: { reporter: ["text", "json", "html"], }, From 457907e01fc7dc4fd3c06b2f081cb80c1a15b369 Mon Sep 17 00:00:00 2001 From: Tiberius Silivestru Date: Tue, 9 Dec 2025 21:27:13 -0700 Subject: [PATCH 6/8] removing token from ci job --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91ebc56..4a8485f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,6 +54,5 @@ jobs: if: matrix.node-version == 22 uses: codecov/codecov-action@v4 with: - token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage/coverage-final.json fail_ci_if_error: false From 87449fe3da93ff07c95707bb052e39f12ea8ef0c Mon Sep 17 00:00:00 2001 From: Tiberius Silivestru Date: Wed, 10 Dec 2025 09:25:58 -0700 Subject: [PATCH 7/8] update changelog --- CHANGELOG.md | 71 ++++++++++++++++------------------------------------ 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a4b57b..ffbcf42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,81 +2,52 @@ All notable changes to this project will be documented in this file. -## [0.3.1] - 2025-12-09 +## [0.3.2] - 2025-12-10 ### Changed -- **Build Process Simplification**: Removed wrapper script complexity in favor of direct SWC compilation -- **Postbuild Script**: Replaced `insert-shebang.sh` with lightweight `add-shebang.js` Node script -- **CJS Package Generation**: Now generated inline in build script instead of via wrapper -- **README**: Updated "How It Works" section to reflect simplified build architecture -- **GitHub Actions**: Added CI workflow for automated testing on Node 20 and 22 +- **CI**: Main-only triggers, concurrency cancellation, Node 20/22 matrix, unit tests run with coverage +- **Tests**: Unit and integration suites split into separate Vitest configs +- **Build**: CI builds once (`build:ci`) before running integration tests; Codecov upload is best-effort -### Technical Details +### Fixed -Build Process (Simplified): +- **Integration CI**: Missing build outputs resolved by running build ahead of integration and skipping format:fix in CI -1. Prebuild: format:fix → lint → typecheck → clean -2. Compile: SWC compiles source to both `build/esm/src/` and `build/cjs/src/` -3. Path Resolution: `tsc-alias` transforms `@/` imports to relative paths -4. Executables: `add-shebang.js` adds shebangs and sets executable permissions -5. CJS Marker: `package.json` with `"type":"commonjs"` created in `build/cjs/` +## [0.3.1] - 2025-12-09 -Entry Points: +### Changed -- ESM: `build/esm/src/cli.js` (executable) -- CJS: `build/cjs/src/cli.js` (executable) +- **Build**: Simplified to direct SWC outputs plus a lightweight `add-shebang.js` script +- **Docs**: README "How It Works" refreshed for the new build shape +- **CI**: Added GitHub Actions on Node 20/22 ## [0.3.0] - 2025-12-09 ### Added -- **Dual Build System**: Project compiles to both ESM (`build/esm/`) and CommonJS (`build/cjs/`) with proper module format markers -- **Path Aliases**: TypeScript path aliases (`@/*`) work throughout codebase and resolve to relative paths in output -- **Build Validation**: Code quality checks (format, lint, typecheck) run automatically in prebuild step -- **Source Maps**: Both ESM and CJS builds include source maps for debugging -- **ESM dirname Utility**: New `getDirname()` utility for ES module-compatible directory resolution -- **Comprehensive Tests**: 27 total tests (9 unit + 18 integration) with 100% code coverage -- **Integration Test Suite**: Dedicated `tests/integration/` with build output and module format validation -- **JSDoc Comments**: All functions documented for IDE support and clarity -- **Improved README**: Comprehensive documentation with features, usage, and architecture explanation +- **Dual Outputs**: ESM and CJS builds with source maps and path alias resolution +- **Tests**: 27 total (unit + integration) plus coverage; integration suite validates build outputs +- **Docs**: README expanded; JSDoc coverage improved ### Changed -- **Tooling Migration**: Replaced ESLint + Prettier with Biome for unified linting/formatting -- **Node Version**: Updated from 16+ to 20+ for stable ESM support without flags -- **Build Scripts**: Restructured with separate SWC configurations for ESM and CJS -- **CLI Implementation**: Enhanced with better error handling and version management -- **Testing Framework**: Upgraded from Vite test to dedicated Vitest with coverage -- **Project Structure**: Added utilities folder and proper test file organization +- **Tooling**: ESLint/Prettier replaced by Biome; Vitest adopted with coverage +- **Runtime**: Node requirement raised to 20+ for stable ESM; build scripts split per format ### Removed -- ESLint configuration and plugins -- Prettier configuration -- Old single build configuration (`.swcrc`) -- Unreachable Node version check code +- Legacy lint/format configs and the single `.swcrc` +- Unreachable Node version guard ### Fixed -- Test file exclusion from production builds -- Path alias transformation for both module formats -- Vitest configuration to prevent test discovery in build directory -- CJS module format declaration +- Test files excluded from builds; aliases resolved correctly; build dir no longer scanned by tests ### Dependencies Updated -- TypeScript: 4.9.5 → 5.9.3 -- SWC: 1.3.35 → 1.15.3 -- Commander: 10.0.0 → 14.0.2 -- Vitest: 0.28.5 → 4.0.15 -- Biome: 2.3.8 (new) -- tsc-alias: 1.8.16 (new) -- @vitest/coverage-v8: 4.0.15 (new) +- TypeScript, SWC, Commander, Vitest, Biome, tsc-alias, @vitest/coverage-v8 ### Breaking Changes -- Requires Node.js 20+ (was 16+) -- Dual ESM/CJS structure replaces single build output -- Package exports field specifies import/require conditions -- CLI now uses Biome instead of ESLint/Prettier +- Requires Node 20+ and dual ESM/CJS outputs; exports now specify import/require conditions From ae8ee222565b72cca049ebf7f90e65c17053318d Mon Sep 17 00:00:00 2001 From: Tiberius Silivestru Date: Wed, 10 Dec 2025 09:56:35 -0700 Subject: [PATCH 8/8] one more changelog tweak --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffbcf42..e152c72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,6 @@ All notable changes to this project will be documented in this file. - **Tests**: Unit and integration suites split into separate Vitest configs - **Build**: CI builds once (`build:ci`) before running integration tests; Codecov upload is best-effort -### Fixed - -- **Integration CI**: Missing build outputs resolved by running build ahead of integration and skipping format:fix in CI - ## [0.3.1] - 2025-12-09 ### Changed