
Testing Cicd Init
- 135 installs
- 31 repo stars
- Updated August 2, 2026
- shipshitdev/library
Bootstrap test runners, coverage hooks, and CI pipelines for a new repo so every PR gets automated checks before merge or deploy.
About
testing-cicd-init from shipshitdev/library scaffolds automated test suites and CI workflows for new projects so merges and deploys run through consistent quality gates from day one.
- CI pipeline bootstrap
- Test runner setup
- PR quality gates
- Coverage and automation hooks
Testing Cicd Init by the numbers
- 135 all-time installs (skills.sh)
- +4 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #482 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/shipshitdev/library --skill testing-cicd-initAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 135 |
|---|---|
| repo stars | ★ 31 |
| Last updated | August 2, 2026 |
| Repository | shipshitdev/library ↗ |
What it does
Bootstrap test runners, coverage hooks, and CI pipelines for a new repo so every PR gets automated checks before merge or deploy.
Files
Testing & CI/CD Initialization
Automatically sets up comprehensive test infrastructure for TypeScript projects including Vitest, coverage thresholds, and GitHub Actions CI/CD.
Contract
Inputs:
- Project root directory (current working directory by default).
- Project type is auto-detected from
package.jsonand config files; can be specified explicitly (nextjs, nestjs, react, node).
Outputs:
vitest.config.tsconfigured for detected environment.- Test setup file (
src/test/setup.tsfor Next.js/React,test/setup.tsfor NestJS). .github/workflows/ci.ymlwith Bun-based pipeline and coverage enforcement.- Updated
package.jsonscripts (test,test:coverage,typecheck).
Creates/Modifies:
vitest.config.ts(created).- Test setup file (created).
.github/workflows/ci.yml(created or updated).package.jsonscripts section (updated).
External Side Effects:
- Runs
bun add -Dto install Vitest and related testing packages.
Confirmation Required:
- None. All changes are applied immediately on invocation.
Delegates To:
husky-test-coverageskill for adding pre-commit coverage gate (optional, not auto-invoked).playwright-e2e-initfor E2E layer (optional, not auto-invoked).
When to Use
This skill should be used when:
- Adding tests to a project without test coverage
- Setting up GitHub Actions CI/CD for the first time
- Configuring Vitest with coverage thresholds
- Initializing testing infrastructure for a new project
- Migrating from Jest to Vitest
What It Does
1. Detects project type (Next.js, NestJS, React, Node.js) 2. Adds Vitest configuration with appropriate settings 3. Creates test setup files for the environment 4. Adds GitHub Actions workflow for CI/CD 5. Configures 80% coverage thresholds 6. Adds test scripts to package.json 7. Installs required dependencies
Project Type Detection
The skill detects project type by scanning:
package.jsondependencies (next, @nestjs/core, react, etc.)- Config files (next.config.*, nest-cli.json, etc.)
- Directory structure (app/, src/, pages/, etc.)
Quick Start
Example prompt:
Add testing and CI/CD to this projectOr be specific:
Set up Vitest with 80% coverage and GitHub Actions for this Next.js projectConfiguration by Project Type
Next.js Projects
Dependencies installed:
bun add -D vitest @vitest/coverage-v8 @vitejs/plugin-react @testing-library/react @testing-library/jest-dom jsdomFiles created:
vitest.config.ts- Vitest with jsdom environmentsrc/test/setup.ts- Test setup with RTL matchers.github/workflows/ci.yml- CI pipeline
Test pattern: **/*.{test,spec}.{ts,tsx}
NestJS Projects
Dependencies installed:
bun add -D vitest @vitest/coverage-v8 supertest @types/supertestFiles created:
vitest.config.ts- Vitest with node environmenttest/setup.ts- Test setup for NestJS.github/workflows/ci.yml- CI with MongoDB service
Test pattern: src/**/*.spec.ts
React/Node.js Projects
Follows similar patterns based on detected framework.
Coverage Configuration
Default thresholds (configurable):
- Lines: 80%
- Functions: 80%
- Branches: 75%
- Statements: 80%
Coverage is enforced:
1. In pre-commit hooks (via Husky) 2. In CI/CD pipeline (GitHub Actions)
GitHub Actions Features
The generated CI workflow includes:
- Bun setup with caching
- Dependency installation
- Lint/format checking (Biome)
- TypeScript type checking
- Test execution with coverage
- Build verification
- MongoDB service (for NestJS projects)
Templates
Templates are located in the templates/ directory:
| Template | Purpose |
|---|---|
vitest.config.nextjs.ts | Vitest config for Next.js |
vitest.config.nestjs.ts | Vitest config for NestJS |
ci-nextjs.yml | GitHub Actions for Next.js |
ci-nestjs.yml | GitHub Actions for NestJS |
test-setup-react.ts | Test setup with RTL |
test-setup-node.ts | Test setup for Node.js |
Monorepo Support
For monorepos (detected by workspaces in package.json):
1. Creates vitest.workspace.ts at root 2. Creates individual vitest.config.ts per package 3. Creates root-level GitHub Actions workflow 4. Uses bun --filter '*' test for orchestration
Integration with Other Skills
| Skill | Integration |
|---|---|
husky-test-coverage | Adds pre-commit coverage enforcement |
linter-formatter-init | Works alongside for code quality |
playwright-e2e-init | Adds E2E testing after unit tests |
testing-expert | Provides testing patterns guidance |
Example Usage
Adding tests to a Next.js project
User: Add testing to this project
Agent:
1. Detects Next.js from package.json
2. Installs vitest, @vitest/coverage-v8, @testing-library/react
3. Creates vitest.config.ts with jsdom environment
4. Creates src/test/setup.ts
5. Creates .github/workflows/ci.yml
6. Adds test scripts to package.jsonAdding tests to a NestJS API
User: Set up tests for this NestJS API
Agent:
1. Detects NestJS from @nestjs/core dependency
2. Installs vitest, @vitest/coverage-v8, supertest
3. Creates vitest.config.ts with node environment
4. Creates test/setup.ts
5. Creates .github/workflows/ci.yml with MongoDB service
6. Adds test scripts to package.jsonTroubleshooting
Tests not finding modules
Ensure path aliases in vitest.config.ts match tsconfig.json:
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},Coverage below threshold
1. Check coverage report: bun test --coverage 2. Identify uncovered lines 3. Add tests or adjust thresholds temporarily
CI failing on type errors
Ensure bunx tsc --noEmit passes locally before pushing.
Best Practices
1. Start with unit tests for utilities and services 2. Add integration tests for API endpoints 3. Use E2E tests sparingly for critical flows 4. Run tests before commits via Husky 5. Monitor coverage trends in CI
{
"name": "testing-cicd-init",
"version": "1.0.0",
"description": "Add Vitest testing infrastructure and GitHub Actions CI/CD to any TypeScript project. Supports Next.",
"author": {
"name": "Ship Shit Dev",
"email": "hello@shipshit.dev",
"url": "https://shipshit.dev"
},
"license": "MIT",
"skills": "."
}
name: CI
on:
push:
branches: [master, main]
pull_request:
branches: [master, main]
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
services:
mongodb:
image: mongo:7
ports:
- 27017:27017
env:
MONGODB_URI: mongodb://localhost:27017/test
NODE_ENV: test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Get bun store directory
id: bun-cache
shell: bash
run: echo "STORE_PATH=$(bun pm cache)" >> $GITHUB_OUTPUT
- name: Setup bun cache
uses: actions/cache@v4
with:
path: ${{ steps.bun-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-bun-store-${{ hashFiles('**/bun.lockb') }}
restore-keys: ${{ runner.os }}-bun-store-
- name: Install dependencies
run: bun install --frozen-lockfile || bun install
- name: Lint and format check
run: bun run check
- name: Type check
run: bunx tsc --noEmit
- name: Run tests with coverage
run: bun test --coverage
- name: Build
run: bun run build
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage/lcov.info
fail_ci_if_error: false
continue-on-error: true
name: CI
on:
push:
branches: [master, main]
pull_request:
branches: [master, main]
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Get bun store directory
id: bun-cache
shell: bash
run: echo "STORE_PATH=$(bun pm cache)" >> $GITHUB_OUTPUT
- name: Setup bun cache
uses: actions/cache@v4
with:
path: ${{ steps.bun-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-bun-store-${{ hashFiles('**/bun.lockb') }}
restore-keys: ${{ runner.os }}-bun-store-
- name: Install dependencies
run: bun install --frozen-lockfile || bun install
- name: Lint and format check
run: bun run check
- name: Type check
run: bunx tsc --noEmit
- name: Run tests with coverage
run: bun test --coverage
- name: Build
run: bun run build
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage/lcov.info
fail_ci_if_error: false
continue-on-error: true
import { vi } from "vitest";
// Mock environment variables for tests
process.env.NODE_ENV = "test";
process.env.MONGODB_URI = "mongodb://localhost:27017/test";
// Global test utilities
declare global {
// eslint-disable-next-line no-var
var vi: typeof import("vitest").vi;
}
global.vi = vi;
// Reset mocks between tests
beforeEach(() => {
vi.clearAllMocks();
});
// Cleanup after all tests
afterAll(async () => {
// Close any open handles
vi.restoreAllMocks();
});
import { vi } from "vitest";
import "@testing-library/jest-dom/vitest";
// Mock environment variables for tests
process.env.NODE_ENV = "test";
// Mock Next.js router
vi.mock("next/navigation", () => ({
useRouter: () => ({
push: vi.fn(),
replace: vi.fn(),
prefetch: vi.fn(),
back: vi.fn(),
forward: vi.fn(),
}),
usePathname: () => "/",
useSearchParams: () => new URLSearchParams(),
useParams: () => ({}),
}));
// Mock Next.js Image component
vi.mock("next/image", () => ({
default: ({ src, alt, ...props }: { src: string; alt: string }) => {
// eslint-disable-next-line @next/next/no-img-element
return `<img src="${src}" alt="${alt}" />`;
},
}));
// Reset mocks between tests
beforeEach(() => {
vi.clearAllMocks();
});
import { defineConfig } from "vitest/config";
import path from "path";
export default defineConfig({
test: {
globals: true,
environment: "node",
include: ["src/**/*.spec.ts", "test/**/*.spec.ts"],
exclude: ["node_modules", "dist"],
coverage: {
provider: "v8",
reporter: ["text", "json", "html", "lcov"],
include: ["src/**/*.ts"],
exclude: [
"**/*.spec.ts",
"**/*.test.ts",
"**/*.d.ts",
"src/main.ts",
"**/*.module.ts",
"**/index.ts",
],
thresholds: {
lines: 80,
functions: 80,
branches: 75,
statements: 80,
},
},
setupFiles: ["./test/setup.ts"],
mockReset: true,
restoreMocks: true,
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});
import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
import path from "path";
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: "jsdom",
include: ["**/*.{test,spec}.{ts,tsx}"],
exclude: ["node_modules", ".next", "dist", "e2e"],
coverage: {
provider: "v8",
reporter: ["text", "json", "html", "lcov"],
include: [
"src/**/*.{ts,tsx}",
"app/**/*.{ts,tsx}",
"components/**/*.{ts,tsx}",
"lib/**/*.{ts,tsx}",
],
exclude: [
"**/*.test.*",
"**/*.spec.*",
"**/*.d.ts",
"**/types/**",
"**/__mocks__/**",
"**/test/**",
],
thresholds: {
lines: 80,
functions: 80,
branches: 75,
statements: 80,
},
},
setupFiles: ["./src/test/setup.ts"],
mockReset: true,
restoreMocks: true,
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./"),
"@components": path.resolve(__dirname, "./components"),
"@lib": path.resolve(__dirname, "./lib"),
},
},
});