chore: add husky, commitlint, lint-staged, editorconfig and prettier

This commit is contained in:
Enes Köksal
2026-04-17 22:54:05 +03:00
parent a6bbc50acd
commit 385b61f29b
6 changed files with 197 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
# EditorConfig — https://editorconfig.org
root = true
# All files
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# Markdown
[*.md]
trim_trailing_whitespace = false
# YAML
[*.{yml,yaml}]
indent_size = 2
# JSON
[*.json]
indent_size = 2
# SQL
[*.sql]
indent_size = 4
# Shell scripts
[*.sh]
indent_size = 4
+1
View File
@@ -0,0 +1 @@
bunx --bun commitlint --edit "$1"
+1
View File
@@ -0,0 +1 @@
bun run lint-staged
+13
View File
@@ -0,0 +1,13 @@
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "es5",
"printWidth": 100,
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "always",
"endOfLine": "lf",
"plugins": []
}
+133
View File
@@ -0,0 +1,133 @@
// commitlint.config.js
// Conventional Commits — https://www.conventionalcommits.org/en/v1.0.0/
//
// FORMAT:
// <type>(<scope>): <description>
//
// [optional body]
//
// [optional footer(s)]
//
// EXAMPLES:
// feat(auth): add OAuth2 login with GitHub
// fix(video): resolve HLS buffering on mobile Safari
// docs: update self-hosting guide in README
// chore(deps): bump next from 16.1 to 16.2
// refactor(api): extract pagination helper into lib/utils
// perf(db): add index on Project.createdAt for dashboard query
// ci: configure GitHub Actions matrix for Node 20 and 22
// revert: revert "feat(billing): add yearly plan toggle"
/** @type {import('@commitlint/types').UserConfig} */
const config = {
extends: ["@commitlint/config-conventional"],
// ── Rules ──────────────────────────────────────────────────────────────────
// Each rule is [severity, applicable, value]
// severity 0 = off, 1 = warn, 2 = error
// applicable 'always' | 'never'
rules: {
// ── Type ────────────────────────────────────────────────────────────────
// Must be lowercase (e.g. "feat" not "Feat")
"type-case": [2, "always", "lower-case"],
// Must not be empty
"type-empty": [2, "never"],
// Allowed commit types
"type-enum": [
2,
"always",
[
"feat", // ✨ New feature or user-facing capability
"fix", // 🐛 Bug fix
"docs", // 📝 Documentation only (README, comments, JSDoc)
"style", // 💄 Formatting, whitespace — no logic change
"refactor", // ♻️ Code restructure — no new feature, no bug fix
"perf", // ⚡️ Performance improvement
"test", // 🧪 Adding or correcting tests
"build", // 🏗️ Build system, bundler, or external dependencies
"ci", // 👷 CI/CD pipeline changes (GitHub Actions, Docker, etc.)
"chore", // 🔧 Maintenance tasks not fitting other types
"revert", // ⏪ Reverts a previous commit
"security", // 🔒 Security fix or hardening (not in base config)
"i18n", // 🌐 Internationalisation / translation (not in base)
"dx", // 🛠️ Developer experience (tooling, scripts, configs)
],
],
// ── Scope ───────────────────────────────────────────────────────────────
// Scope must be lowercase when provided (e.g. "auth" not "Auth")
"scope-case": [2, "always", "lower-case"],
// Scope is optional — no rule enforced for "scope-empty"
// Suggested scopes (not enforced):
// auth, api, db, video, billing, admin, ci, deps, ui, email,
// invitations, workspace, project, storage, notifications, onboarding
// ── Subject (short description) ─────────────────────────────────────────
// Must not be empty
"subject-empty": [2, "never"],
// Must NOT start with an uppercase letter
// Good: "add retry logic for upload"
// Bad: "Add retry logic for upload"
"subject-case": [2, "never", ["sentence-case", "start-case", "pascal-case", "upper-case"]],
// Must NOT end with a period
"subject-full-stop": [2, "never", "."],
// Max 100 chars for the subject line (type + scope + description)
"header-max-length": [2, "always", 100],
// Min 10 chars to prevent meaningless one-word subjects
"subject-min-length": [2, "always", 10],
// ── Body ────────────────────────────────────────────────────────────────
// Body lines should be wrapped at 120 chars
"body-max-line-length": [2, "always", 120],
// Blank line required between subject and body
"body-leading-blank": [2, "always"],
// ── Footer ──────────────────────────────────────────────────────────────
// Blank line required between body and footer
"footer-leading-blank": [1, "always"],
// Footer lines should be wrapped at 120 chars
"footer-max-line-length": [2, "always", 120],
},
// ── Prompt (interactive `bun run commit`) ──────────────────────────────────
// Shown when using @commitlint/prompt-cli or czg
prompt: {
questions: {
type: {
description: "Select the type of change you are committing",
enum: {
feat: { description: "A new feature", title: "Features", emoji: "✨" },
fix: { description: "A bug fix", title: "Bug Fixes", emoji: "🐛" },
docs: { description: "Documentation only changes", title: "Documentation", emoji: "📝" },
style: { description: "Formatting, missing semicolons, etc.", title: "Styles", emoji: "💄" },
refactor: { description: "A code change without feature or fix", title: "Refactors", emoji: "♻️" },
perf: { description: "A performance improvement", title: "Performance", emoji: "⚡️" },
test: { description: "Adding or correcting tests", title: "Tests", emoji: "🧪" },
build: { description: "Build system or dependency changes", title: "Builds", emoji: "🏗️" },
ci: { description: "CI/CD configuration changes", title: "CI", emoji: "👷" },
chore: { description: "Other changes (tooling, maintenance)", title: "Chores", emoji: "🔧" },
revert: { description: "Reverts a previous commit", title: "Reverts", emoji: "⏪" },
security: { description: "A security fix or hardening", title: "Security", emoji: "🔒" },
i18n: { description: "Internationalisation / translation", title: "i18n", emoji: "🌐" },
dx: { description: "Developer experience improvements", title: "DX", emoji: "🛠️" },
},
},
},
},
};
export default config;
+17
View File
@@ -9,8 +9,11 @@
"start": "next start", "start": "next start",
"start:docker": "sh ./scripts/docker-entrypoint.sh", "start:docker": "sh ./scripts/docker-entrypoint.sh",
"lint": "eslint --max-warnings=0", "lint": "eslint --max-warnings=0",
"format": "prettier --write .",
"format:check": "prettier --check .",
"typecheck": "tsc --noEmit", "typecheck": "tsc --noEmit",
"check": "bun run lint && bun run typecheck", "check": "bun run lint && bun run typecheck",
"prepare": "husky",
"postinstall": "prisma generate", "postinstall": "prisma generate",
"db:generate": "prisma generate", "db:generate": "prisma generate",
"db:push": "prisma db push", "db:push": "prisma db push",
@@ -62,10 +65,24 @@
"@types/react-dom": "^19", "@types/react-dom": "^19",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "16.1.6", "eslint-config-next": "16.1.6",
"@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.8.1",
"husky": "^9.1.7",
"lint-staged": "^15.5.1",
"prettier": "^3.5.3",
"shadcn": "^3.8.3", "shadcn": "^3.8.3",
"tailwindcss": "^4", "tailwindcss": "^4",
"typescript": "^5" "typescript": "^5"
}, },
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --max-warnings=0 --fix",
"prettier --write"
],
"*.{json,css,md,yml,yaml,mdx}": [
"prettier --write"
]
},
"ignoreScripts": [ "ignoreScripts": [
"sharp", "sharp",
"unrs-resolver" "unrs-resolver"