Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions .github/workflows/frontend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ on:
branches: [main]
types: [opened, reopened, synchronize, ready_for_review]

# ๋น ๋ฅธ ํ”ผ๋“œ๋ฐฑ: ๊ธฐ๋Šฅ/์ž‘์—… ๋ธŒ๋žœ์น˜์— push๋  ๋•Œ CI ์‹คํ–‰
# ๋น ๋ฅธ ํ”ผ๋“œ๋ฐฑ: ์ž‘์—… ๋ธŒ๋žœ์น˜์— push๋  ๋•Œ CI ์‹คํ–‰ (โš ๏ธ ๋Œ€๋ฌธ์ž ๋„ค์ด๋ฐ๋งŒ ํ—ˆ์šฉ)
push:
branches:
- "Feature/*"
- "Fix/*"
- "Chore/*"
- "Docs/*"
- "Test/*"
- "Refactor/*"
- "Feature/**"
- "Fix/**"
- "Chore/**"
- "Docs/**"
- "Test/**"
- "Refactor/**"

# (์„ ํƒ) Actions ํƒญ์—์„œ ์ˆ˜๋™ ์‹คํ–‰ ๋ฒ„ํŠผ
workflow_dispatch: {}
Expand All @@ -23,34 +23,51 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
NODE_VERSION: "20.19.2"
CI: "true"

jobs:
lint:
name: Style & Lint
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}

- uses: pnpm/action-setup@v4
with:
run_install: false

- name: Get pnpm store directory
id: pnpm-cache
run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

- uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-pnpm-

- run: pnpm install --frozen-lockfile
- run: pnpm run --if-present lint

- name: Prettier check
run: pnpm run --if-present format:check

- name: ESLint
run: pnpm run --if-present lint

test:
runs-on: ubuntu-latest
needs: lint
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -73,6 +90,7 @@ jobs:
build:
runs-on: ubuntu-latest
needs: test
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -90,4 +108,13 @@ jobs:
key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-pnpm-
- run: pnpm install --frozen-lockfile

# (์„ ํƒ) Next.js ๋นŒ๋“œ ์บ์‹œ
# - uses: actions/cache@v4
# with:
# path: |
# .next/cache
# key: ${{ runner.os }}-next-${{ hashFiles('pnpm-lock.yaml', 'next.config.*', '**/*.{ts,tsx,js,jsx,css,scss,md,mdx}') }}
# restore-keys: ${{ runner.os }}-next-

- run: pnpm run build
10 changes: 10 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

pnpm commitlint --edit "$1" || {
echo
echo "โŒ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ๊ทœ์น™ ์œ„๋ฐ˜!"
echo " ํ˜•์‹: CDP-์ˆซ์ž type์ด๋ชจ์ง€(scope): subject"
echo " ์˜ˆ์‹œ: CDP-31 fix๐Ÿ›(ci): CI error resolution"
echo " ํ—ˆ์šฉ: featโœจ, fix๐Ÿ›, refactor๐Ÿ”จ, style๐ŸŽจ, choreโš™๏ธ, docs๐Ÿ“, test๐Ÿงช"
Comment on lines +3 to +8

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Use pnpm exec for commitlint in commit-msg hook

The commit message hook invokes pnpm commitlint, but pnpm cannot find that command because the repo defines no commitlint script. This means every commit will abort with โ€œCommand "commitlint" not foundโ€ and the message is never checked. Run pnpm exec commitlint --edit "$1" (or add a commitlint script) to make the hook work.

Useful? React with ๐Ÿ‘ย / ๐Ÿ‘Ž.

exit 1
}
63 changes: 63 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

echo "๐Ÿ”Ž pre-commit: lint-staged ์‹คํ–‰ ๋ฐ ์ตœ์ข… ์ ๊ฒ€ ์‹œ์ž‘"

# 0) ์ปค๋ฐ‹์— ํฌํ•จ๋œ ํŒŒ์ผ ๋ชฉ๋ก (์ถ”๊ฐ€/๋ณต์‚ฌ/์ˆ˜์ •)
STAGED_FILES="$(git diff --name-only --cached --diff-filter=ACMR)"
if [ -z "$STAGED_FILES" ]; then
echo "โ„น๏ธ ์Šคํ…Œ์ด์ง•๋œ ํŒŒ์ผ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค."
exit 0
fi

# 1) ๋ณ€๊ฒฝ ํŒŒ์ผ๋งŒ ์ž๋™ ์ˆ˜์ • (eslint --fix, prettier --write)
if ! pnpm lint-staged; then
echo
Comment on lines +13 to +15

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Call lint-staged via pnpm exec to avoid hook failures

The new pre-commit hook runs pnpm lint-staged, but pnpm only executes binaries this way when a script with that name exists. There is no lint-staged script in package.json, so every commit will fail with ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL Command "lint-staged" not found. Either add a "lint-staged": "lint-staged" script or invoke the binary with pnpm exec lint-staged so the hook can run.

Useful? React with ๐Ÿ‘ย / ๐Ÿ‘Ž.

echo "โŒ lint-staged ๋‹จ๊ณ„์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."
echo " - ์ž๋™์ˆ˜์ • ๋ถˆ๊ฐ€ํ•œ ๋ฆฐํŠธ ์—๋Ÿฌ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์–ด์š”."
echo " - ๋กœ์ปฌ์—์„œ 'pnpm lint'๋กœ ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๊ณ  ์ˆ˜์ •ํ•œ ๋’ค ๋‹ค์‹œ ์ปค๋ฐ‹ํ•˜์„ธ์š”."
exit 1
fi

# 2) ์ตœ์ข… ์ ๊ฒ€: ์Šคํ…Œ์ด์ง•๋œ ํŒŒ์ผ๋งŒ ๋Œ€์ƒ์œผ๋กœ ๊ฒ€์‚ฌ(์ˆ˜์ • ์—†์ด ์‹คํŒจ๋งŒ ๊ฐ์ง€)
PRETTIER_FAIL=0
ESLINT_FAIL=0

# ๊ฐœํ–‰๋งŒ ๊ตฌ๋ถ„์ž๋กœ ์‚ฌ์šฉ (๊ณต๋ฐฑ ํฌํ•จ ํŒŒ์ผ๋ช… ์•ˆ์ „)
IFS="$(printf '\n')"
for f in $STAGED_FILES; do
case "$f" in
*.js|*.jsx|*.ts|*.tsx|*.json|*.css|*.md)
# Prettier ํฌ๋งท ์ค€์ˆ˜ ํ™•์ธ (์ˆ˜์ • ์—†์ด ๊ฒ€์‚ฌ)
pnpm -s prettier --check "$f" || PRETTIER_FAIL=1
;;
esac
done

for f in $STAGED_FILES; do
case "$f" in
*.js|*.jsx|*.ts|*.tsx)
# ESLint ์ตœ์ข… ํ™•์ธ (์ˆ˜์ • ์—†์ด ๊ฒ€์‚ฌ)
pnpm -s eslint --max-warnings=0 "$f" || ESLINT_FAIL=1
;;
esac
done
unset IFS

if [ "$PRETTIER_FAIL" -ne 0 ]; then
echo
echo "โŒ Prettier ํฌ๋งท ์œ„๋ฐ˜์ด ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค."
echo " - 'pnpm format' ํ›„ ๋‹ค์‹œ ์ปค๋ฐ‹ํ•˜์„ธ์š”."
exit 1
fi

if [ "$ESLINT_FAIL" -ne 0 ]; then
echo
echo "โŒ ESLint ์œ„๋ฐ˜์ด ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค."
echo " - 'pnpm lint:fix' ๋˜๋Š” ์ˆ˜๋™ ์ˆ˜์ • ํ›„ ๋‹ค์‹œ ์ปค๋ฐ‹ํ•˜์„ธ์š”."
exit 1
fi

COUNT="$(printf '%s\n' "$STAGED_FILES" | wc -l | tr -d ' ')"
echo "โœ… pre-commit ํ†ต๊ณผ: ${COUNT}๊ฐœ ํŒŒ์ผ ์ ๊ฒ€ ์™„๋ฃŒ"
exit 0
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
.next
out
dist
coverage
.turbo
public/generated
12 changes: 12 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "lf",
"proseWrap": "preserve"
}
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ develop์— ๋จธ์ง€๋œ ๊ธฐ๋Šฅ์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ์ ๊ฒ€ํ•œ ์ดํ›„์— main ๋ธŒ
### 2. ํ˜‘์—… ๊ณผ์ •

1. **Feature ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ ๋ฐ ๊ฐœ๋ฐœ**

- ๋กœ์ปฌ์—์„œ `develop` ๋ธŒ๋žœ์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ Feature ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

```bash
Expand All @@ -83,7 +82,6 @@ develop์— ๋จธ์ง€๋œ ๊ธฐ๋Šฅ์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ์ ๊ฒ€ํ•œ ์ดํ›„์— main ๋ธŒ
- ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์ด ๋๋‚ฌ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ ์ปค๋ฐ‹์„ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค. (์•„๋ž˜ [์ปค๋ฐ‹ ์ปจ๋ฒค์…˜](#6-์ปค๋ฐ‹-์ปจ๋ฒค์…˜)์„ ๊ผญ ํ™•์ธํ•ด ์ฃผ์„ธ์š”!)

2. **ํ‘ธ์‰ฌ & PR ์ƒ์„ฑ (๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ์ ๊ฒ€์šฉ)**

- ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์ด ๋๋‚œ Feature ๋ธŒ๋žœ์น˜๋ฅผ ์›๊ฒฉ ์ €์žฅ์†Œ์— ํ‘ธ์‰ฌํ•ฉ๋‹ˆ๋‹ค.

```bash
Expand Down Expand Up @@ -111,12 +109,10 @@ develop์— ๋จธ์ง€๋œ ๊ธฐ๋Šฅ์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ์ ๊ฒ€ํ•œ ์ดํ›„์— main ๋ธŒ
```

3. **Squash Merge**

- PR์„ ๋ณธ์ธ์ด ์ง์ ‘ **Squash Merge** ํ•ฉ๋‹ˆ๋‹ค.
- ๋จธ์ง€๋œ Feature ๋ธŒ๋žœ์น˜๋Š” ์ž๋™ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

4. **develop ์ ๊ฒ€ โ†’ main ๋ฐฐํฌ (๋ฐฐํฌ ์ ๊ฒ€์šฉ)**

- `develop`์— ๋จธ์ง€๋œ ๊ธฐ๋Šฅ์ด ์ •์ƒ ๋™์ž‘ํ•˜๋Š”์ง€ ์ ๊ฒ€ํ•ฉ๋‹ˆ๋‹ค.
- ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด `main` ๋ธŒ๋žœ์น˜๋กœ ๋จธ์ง€ํ•˜์—ฌ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.
- ์ด๋•Œ PR์„ ์ƒ์„ฑํ•˜๊ณ  ์•„๋ž˜ ํ…œํ”Œ๋ฆฟ์„ ์ฑ„์›Œ์ฃผ์„ธ์š”.
Expand All @@ -136,7 +132,6 @@ develop์— ๋จธ์ง€๋œ ๊ธฐ๋Šฅ์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ์ ๊ฒ€ํ•œ ์ดํ›„์— main ๋ธŒ
```

5. **๋ฐฐํฌ ํ›„ ๋กœ์ปฌ ์ตœ์‹ ํ™” & ๋ธŒ๋žœ์น˜ ์ •๋ฆฌ**

- ๋ฐฐํฌ ์ ๊ฒ€์ด ์™„๋ฃŒ๋˜๋ฉด ๋กœ์ปฌ `develop`์„ ์ตœ์‹ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

```bash
Expand Down Expand Up @@ -193,7 +188,6 @@ Refactor/dashboard-layout

- **jira-key**: ํ•ด๋‹น ์ž‘์—… ์ด์Šˆ ํ‚ค (์˜ˆ: CDP-1)
- **type** (๋ชจ๋‘ ์†Œ๋ฌธ์ž):

- feat โœจ: ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€
- fix ๐Ÿ›: ๋ฒ„๊ทธ ์ˆ˜์ •
- refactor ๐Ÿ”จ: ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง (๊ธฐ๋Šฅ ๋ณ€ํ™” ์—†์Œ)
Expand Down
22 changes: 22 additions & 0 deletions commitlint.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/** commitlint.config.cjs */
module.exports = {
extends: ["@commitlint/config-conventional"],
parserPreset: {
parserOpts: {
// CDP-123 choreโš™๏ธ(scope): subject
headerPattern:
/^(CDP-\d+)\s(featโœจ|fix๐Ÿ›|refactor๐Ÿ”จ|style๐ŸŽจ|choreโš™๏ธ|docs๐Ÿ“|test๐Ÿงช)\(([^)]+)\):\s(.+)$/,
headerCorrespondence: ["ticket", "type", "scope", "subject"],
},
},
rules: {
"type-enum": [
2,
"always",
["featโœจ", "fix๐Ÿ›", "refactor๐Ÿ”จ", "style๐ŸŽจ", "choreโš™๏ธ", "docs๐Ÿ“", "test๐Ÿงช"],
],
"scope-empty": [2, "never"],
"subject-empty": [2, "never"],
"header-max-length": [2, "always", 120],
},
};
24 changes: 10 additions & 14 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
// eslint.config.mjs
import { FlatCompat } from "@eslint/eslintrc";
import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const compat = new FlatCompat({
baseDirectory: __dirname,
});
const compat = new FlatCompat({ baseDirectory: __dirname });

const config = [
// Next ๊ถŒ์žฅ + TS + Prettier ์ถ”์ฒœ(FlatCompat๋กœ ๋ ˆ๊ฑฐ์‹œ ํ™•์žฅ ๋ณ€ํ™˜)
...compat.extends("next/core-web-vitals", "next/typescript", "plugin:prettier/recommended"),

const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
// ๋ฌด์‹œ ๋ชฉ๋ก
{
ignores: [
"node_modules/**",
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
],
ignores: ["node_modules/**", ".next/**", "out/**", "build/**", "next-env.d.ts"],
},
];

export default eslintConfig;
export default config;
23 changes: 22 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,20 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
"lint": "eslint . --ext .js,.jsx,.ts,.tsx --max-warnings=0",
"lint:fix": "pnpm lint --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"prepare": "husky"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,css,md}": [
"prettier --write"
]
},
"dependencies": {
"@fontsource/pretendard": "^5.2.5",
Expand All @@ -16,13 +29,21 @@
"react-dom": "19.1.0"
},
"devDependencies": {
"@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.8.1",
"@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "15.5.3",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.4",
"husky": "^9.1.7",
"lint-staged": "^16.2.0",
"prettier": "^3.6.2",
"prettier-plugin-tailwindcss": "^0.6.14",
"tailwindcss": "^4",
"typescript": "^5"
}
Expand Down
Loading