feat(auth): JWT 기반 Google 로그인 인증 API 구현 #1
14
.claude/scripts/on-commit.sh
Executable file
14
.claude/scripts/on-commit.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
INPUT=$(cat)
|
||||
COMMAND=$(echo "$INPUT" | python3 -c "import sys,json;print(json.load(sys.stdin).get('tool_input',{}).get('command',''))" 2>/dev/null || echo "")
|
||||
if echo "$COMMAND" | grep -qE 'git commit'; then
|
||||
cat <<RESP
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"additionalContext": "커밋이 감지되었습니다. 다음을 수행하세요:\n1. docs/CHANGELOG.md에 변경 내역 추가\n2. memory/project-snapshot.md에서 변경된 부분 업데이트\n3. memory/project-history.md에 이번 변경사항 추가\n4. API 인터페이스 변경 시 memory/api-types.md 갱신\n5. 프로젝트에 lint 설정이 있다면 lint 결과를 확인하고 문제를 수정"
|
||||
}
|
||||
}
|
||||
RESP
|
||||
else
|
||||
echo '{}'
|
||||
fi
|
||||
23
.claude/scripts/on-post-compact.sh
Executable file
23
.claude/scripts/on-post-compact.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
INPUT=$(cat)
|
||||
CWD=$(echo "$INPUT" | python3 -c "import sys,json;print(json.load(sys.stdin).get('cwd',''))" 2>/dev/null || echo "")
|
||||
if [ -z "$CWD" ]; then
|
||||
CWD=$(pwd)
|
||||
fi
|
||||
PROJECT_HASH=$(echo "$CWD" | sed 's|/|-|g')
|
||||
MEMORY_DIR="$HOME/.claude/projects/$PROJECT_HASH/memory"
|
||||
CONTEXT=""
|
||||
if [ -f "$MEMORY_DIR/MEMORY.md" ]; then
|
||||
SUMMARY=$(head -100 "$MEMORY_DIR/MEMORY.md" | python3 -c "import sys;print(sys.stdin.read().replace('\\\\','\\\\\\\\').replace('\"','\\\\\"').replace('\n','\\\\n'))" 2>/dev/null)
|
||||
CONTEXT="컨텍스트가 압축되었습니다.\\n\\n[세션 요약]\\n${SUMMARY}"
|
||||
fi
|
||||
if [ -f "$MEMORY_DIR/project-snapshot.md" ]; then
|
||||
SNAP=$(head -50 "$MEMORY_DIR/project-snapshot.md" | python3 -c "import sys;print(sys.stdin.read().replace('\\\\','\\\\\\\\').replace('\"','\\\\\"').replace('\n','\\\\n'))" 2>/dev/null)
|
||||
CONTEXT="${CONTEXT}\\n\\n[프로젝트 최신 상태]\\n${SNAP}"
|
||||
fi
|
||||
if [ -n "$CONTEXT" ]; then
|
||||
CONTEXT="${CONTEXT}\\n\\n위 내용을 참고하여 작업을 이어가세요. 상세 내용은 memory/ 디렉토리의 각 파일을 참조하세요."
|
||||
echo "{\"hookSpecificOutput\":{\"additionalContext\":\"${CONTEXT}\"}}"
|
||||
else
|
||||
echo "{\"hookSpecificOutput\":{\"additionalContext\":\"컨텍스트가 압축되었습니다. memory 파일이 없으므로 사용자에게 이전 작업 내용을 확인하세요.\"}}"
|
||||
fi
|
||||
8
.claude/scripts/on-pre-compact.sh
Executable file
8
.claude/scripts/on-pre-compact.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
# PreCompact hook: systemMessage만 지원 (hookSpecificOutput 사용 불가)
|
||||
INPUT=$(cat)
|
||||
cat <<RESP
|
||||
{
|
||||
"systemMessage": "컨텍스트 압축이 시작됩니다. 반드시 다음을 수행하세요:\n\n1. memory/MEMORY.md - 핵심 작업 상태 갱신 (200줄 이내)\n2. memory/project-snapshot.md - 변경된 패키지/타입 정보 업데이트\n3. memory/project-history.md - 이번 세션 변경사항 추가\n4. memory/api-types.md - API 인터페이스 변경이 있었다면 갱신\n5. 미완료 작업이 있다면 TodoWrite에 남기고 memory에도 기록"
|
||||
}
|
||||
RESP
|
||||
@ -43,5 +43,42 @@
|
||||
"Read(./**/application-local.yml)",
|
||||
"Read(./**/application-local.properties)"
|
||||
]
|
||||
},
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "compact",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/scripts/on-post-compact.sh",
|
||||
"timeout": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreCompact": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/scripts/on-pre-compact.sh",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/scripts/on-commit.sh",
|
||||
"timeout": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,22 +22,142 @@ $ARGUMENTS가 "auto"이거나 비어있으면 다음 순서로 감지:
|
||||
- 빌드 파일, 설정 파일, 디렉토리 구조 파악
|
||||
- 사용 중인 프레임워크, 라이브러리 감지
|
||||
- 기존 `.claude/` 디렉토리 존재 여부 확인
|
||||
- eslint, prettier, checkstyle, spotless 등 lint 도구 설치 여부 확인
|
||||
|
||||
### 2. CLAUDE.md 생성
|
||||
프로젝트 루트에 CLAUDE.md를 생성하고 다음 내용 포함:
|
||||
- 프로젝트 개요 (이름, 타입, 주요 기술 스택)
|
||||
- 빌드/실행 명령어 (감지된 빌드 도구 기반)
|
||||
- 테스트 실행 명령어
|
||||
- lint 실행 명령어 (감지된 도구 기반)
|
||||
- 프로젝트 디렉토리 구조 요약
|
||||
- 팀 컨벤션 참조 (`.claude/rules/` 안내)
|
||||
|
||||
### 3. .claude/ 디렉토리 구성
|
||||
이미 팀 표준 파일이 존재하면 건너뜀. 없는 경우:
|
||||
- `.claude/settings.json` — 프로젝트 타입별 표준 권한 설정
|
||||
- `.claude/rules/` — 팀 규칙 파일 (team-policy, git-workflow, code-style, naming, testing)
|
||||
- `.claude/skills/` — 팀 스킬 (create-mr, fix-issue, sync-team-workflow)
|
||||
### Gitea 파일 다운로드 URL 패턴
|
||||
⚠️ Gitea raw 파일은 반드시 **web raw URL**을 사용해야 합니다 (`/api/v1/` 경로 사용 불가):
|
||||
```bash
|
||||
GITEA_URL="${GITEA_URL:-https://gitea.gc-si.dev}"
|
||||
# common 파일: ${GITEA_URL}/gc/template-common/raw/branch/develop/<파일경로>
|
||||
# 타입별 파일: ${GITEA_URL}/gc/template-<타입>/raw/branch/develop/<파일경로>
|
||||
# 예시:
|
||||
curl -sf "${GITEA_URL}/gc/template-common/raw/branch/develop/.claude/rules/team-policy.md"
|
||||
curl -sf "${GITEA_URL}/gc/template-react-ts/raw/branch/develop/.editorconfig"
|
||||
```
|
||||
|
||||
### 4. Git Hooks 설정
|
||||
### 3. .claude/ 디렉토리 구성
|
||||
이미 팀 표준 파일이 존재하면 건너뜀. 없는 경우 위의 URL 패턴으로 Gitea에서 다운로드:
|
||||
- `.claude/settings.json` — 프로젝트 타입별 표준 권한 설정 + hooks 섹션 (4단계 참조)
|
||||
- `.claude/rules/` — 팀 규칙 파일 (team-policy, git-workflow, code-style, naming, testing)
|
||||
- `.claude/skills/` — 팀 스킬 (create-mr, fix-issue, sync-team-workflow, init-project)
|
||||
|
||||
### 4. Hook 스크립트 생성
|
||||
`.claude/scripts/` 디렉토리를 생성하고 다음 스크립트 파일 생성 (chmod +x):
|
||||
|
||||
- `.claude/scripts/on-pre-compact.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# PreCompact hook: systemMessage만 지원 (hookSpecificOutput 사용 불가)
|
||||
INPUT=$(cat)
|
||||
cat <<RESP
|
||||
{
|
||||
"systemMessage": "컨텍스트 압축이 시작됩니다. 반드시 다음을 수행하세요:\n\n1. memory/MEMORY.md - 핵심 작업 상태 갱신 (200줄 이내)\n2. memory/project-snapshot.md - 변경된 패키지/타입 정보 업데이트\n3. memory/project-history.md - 이번 세션 변경사항 추가\n4. memory/api-types.md - API 인터페이스 변경이 있었다면 갱신\n5. 미완료 작업이 있다면 TodoWrite에 남기고 memory에도 기록"
|
||||
}
|
||||
RESP
|
||||
```
|
||||
|
||||
- `.claude/scripts/on-post-compact.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
INPUT=$(cat)
|
||||
CWD=$(echo "$INPUT" | python3 -c "import sys,json;print(json.load(sys.stdin).get('cwd',''))" 2>/dev/null || echo "")
|
||||
if [ -z "$CWD" ]; then
|
||||
CWD=$(pwd)
|
||||
fi
|
||||
PROJECT_HASH=$(echo "$CWD" | sed 's|/|-|g')
|
||||
MEMORY_DIR="$HOME/.claude/projects/$PROJECT_HASH/memory"
|
||||
CONTEXT=""
|
||||
if [ -f "$MEMORY_DIR/MEMORY.md" ]; then
|
||||
SUMMARY=$(head -100 "$MEMORY_DIR/MEMORY.md" | python3 -c "import sys;print(sys.stdin.read().replace('\\\\','\\\\\\\\').replace('\"','\\\\\"').replace('\n','\\\\n'))" 2>/dev/null)
|
||||
CONTEXT="컨텍스트가 압축되었습니다.\\n\\n[세션 요약]\\n${SUMMARY}"
|
||||
fi
|
||||
if [ -f "$MEMORY_DIR/project-snapshot.md" ]; then
|
||||
SNAP=$(head -50 "$MEMORY_DIR/project-snapshot.md" | python3 -c "import sys;print(sys.stdin.read().replace('\\\\','\\\\\\\\').replace('\"','\\\\\"').replace('\n','\\\\n'))" 2>/dev/null)
|
||||
CONTEXT="${CONTEXT}\\n\\n[프로젝트 최신 상태]\\n${SNAP}"
|
||||
fi
|
||||
if [ -n "$CONTEXT" ]; then
|
||||
CONTEXT="${CONTEXT}\\n\\n위 내용을 참고하여 작업을 이어가세요. 상세 내용은 memory/ 디렉토리의 각 파일을 참조하세요."
|
||||
echo "{\"hookSpecificOutput\":{\"additionalContext\":\"${CONTEXT}\"}}"
|
||||
else
|
||||
echo "{\"hookSpecificOutput\":{\"additionalContext\":\"컨텍스트가 압축되었습니다. memory 파일이 없으므로 사용자에게 이전 작업 내용을 확인하세요.\"}}"
|
||||
fi
|
||||
```
|
||||
|
||||
- `.claude/scripts/on-commit.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
INPUT=$(cat)
|
||||
COMMAND=$(echo "$INPUT" | python3 -c "import sys,json;print(json.load(sys.stdin).get('tool_input',{}).get('command',''))" 2>/dev/null || echo "")
|
||||
if echo "$COMMAND" | grep -qE 'git commit'; then
|
||||
cat <<RESP
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"additionalContext": "커밋이 감지되었습니다. 다음을 수행하세요:\n1. docs/CHANGELOG.md에 변경 내역 추가\n2. memory/project-snapshot.md에서 변경된 부분 업데이트\n3. memory/project-history.md에 이번 변경사항 추가\n4. API 인터페이스 변경 시 memory/api-types.md 갱신\n5. 프로젝트에 lint 설정이 있다면 lint 결과를 확인하고 문제를 수정"
|
||||
}
|
||||
}
|
||||
RESP
|
||||
else
|
||||
echo '{}'
|
||||
fi
|
||||
```
|
||||
|
||||
`.claude/settings.json`에 hooks 섹션이 없으면 추가 (기존 settings.json의 내용에 병합):
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "compact",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/scripts/on-post-compact.sh",
|
||||
"timeout": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreCompact": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/scripts/on-pre-compact.sh",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash .claude/scripts/on-commit.sh",
|
||||
"timeout": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Git Hooks 설정
|
||||
```bash
|
||||
git config core.hooksPath .githooks
|
||||
```
|
||||
@ -46,7 +166,7 @@ git config core.hooksPath .githooks
|
||||
chmod +x .githooks/*
|
||||
```
|
||||
|
||||
### 5. 프로젝트 타입별 추가 설정
|
||||
### 6. 프로젝트 타입별 추가 설정
|
||||
|
||||
#### java-maven
|
||||
- `.sdkmanrc` 생성 (java=17.0.18-amzn 또는 프로젝트에 맞는 버전)
|
||||
@ -63,7 +183,7 @@ chmod +x .githooks/*
|
||||
- `.npmrc` Nexus 레지스트리 설정 확인
|
||||
- `npm install && npm run build` 성공 확인
|
||||
|
||||
### 6. .gitignore 확인
|
||||
### 7. .gitignore 확인
|
||||
다음 항목이 .gitignore에 포함되어 있는지 확인하고, 없으면 추가:
|
||||
```
|
||||
.claude/settings.local.json
|
||||
@ -73,18 +193,54 @@ chmod +x .githooks/*
|
||||
*.local
|
||||
```
|
||||
|
||||
### 7. workflow-version.json 생성
|
||||
`.claude/workflow-version.json` 파일을 생성하여 현재 글로벌 워크플로우 버전 기록:
|
||||
### 8. Git exclude 설정
|
||||
`.git/info/exclude` 파일을 읽고, 기존 내용을 보존하면서 하단에 추가:
|
||||
|
||||
```gitignore
|
||||
|
||||
# Claude Code 워크플로우 (로컬 전용)
|
||||
docs/CHANGELOG.md
|
||||
*.tmp
|
||||
```
|
||||
|
||||
### 9. Memory 초기화
|
||||
프로젝트 memory 디렉토리의 위치를 확인하고 (보통 `~/.claude/projects/<project-hash>/memory/`) 다음 파일들을 생성:
|
||||
|
||||
- `memory/MEMORY.md` — 프로젝트 분석 결과 기반 핵심 요약 (200줄 이내)
|
||||
- 현재 상태, 프로젝트 개요, 기술 스택, 주요 패키지 구조, 상세 참조 링크
|
||||
- `memory/project-snapshot.md` — 디렉토리 구조, 패키지 구성, 주요 의존성, API 엔드포인트
|
||||
- `memory/project-history.md` — "초기 팀 워크플로우 구성" 항목으로 시작
|
||||
- `memory/api-types.md` — 주요 인터페이스/DTO/Entity 타입 요약
|
||||
- `memory/decisions.md` — 빈 템플릿 (# 의사결정 기록)
|
||||
- `memory/debugging.md` — 빈 템플릿 (# 디버깅 경험 & 패턴)
|
||||
|
||||
### 10. Lint 도구 확인
|
||||
- TypeScript: eslint, prettier 설치 여부 확인. 미설치 시 사용자에게 설치 제안
|
||||
- Java: checkstyle, spotless 등 설정 확인
|
||||
- CLAUDE.md에 lint 실행 명령어가 이미 기록되었는지 확인
|
||||
|
||||
### 11. workflow-version.json 생성
|
||||
Gitea API로 최신 팀 워크플로우 버전을 조회:
|
||||
```bash
|
||||
curl -sf --max-time 5 "https://gitea.gc-si.dev/gc/template-common/raw/branch/develop/workflow-version.json"
|
||||
```
|
||||
조회 성공 시 해당 `version` 값 사용, 실패 시 "1.0.0" 기본값 사용.
|
||||
|
||||
`.claude/workflow-version.json` 파일 생성:
|
||||
```json
|
||||
{
|
||||
"applied_global_version": "1.0.0",
|
||||
"applied_date": "현재날짜",
|
||||
"project_type": "감지된타입"
|
||||
"applied_global_version": "<조회된 버전>",
|
||||
"applied_date": "<현재날짜>",
|
||||
"project_type": "<감지된타입>",
|
||||
"gitea_url": "https://gitea.gc-si.dev"
|
||||
}
|
||||
```
|
||||
|
||||
### 8. 검증 및 요약
|
||||
### 12. 검증 및 요약
|
||||
- 생성/수정된 파일 목록 출력
|
||||
- `git config core.hooksPath` 확인
|
||||
- 빌드 명령 실행 가능 확인
|
||||
- 다음 단계 안내 (개발 시작, 첫 커밋 방법 등)
|
||||
- Hook 스크립트 실행 권한 확인
|
||||
- 다음 단계 안내:
|
||||
- 개발 시작, 첫 커밋 방법
|
||||
- 범용 스킬: `/api-registry`, `/changelog`, `/swagger-spec`
|
||||
|
||||
@ -13,11 +13,11 @@ Gitea API로 template-common 리포의 workflow-version.json 조회:
|
||||
```bash
|
||||
GITEA_URL=$(python3 -c "import json; print(json.load(open('.claude/workflow-version.json')).get('gitea_url', 'https://gitea.gc-si.dev'))" 2>/dev/null || echo "https://gitea.gc-si.dev")
|
||||
|
||||
curl -sf "${GITEA_URL}/api/v1/repos/gc/template-common/raw/workflow-version.json"
|
||||
curl -sf "${GITEA_URL}/gc/template-common/raw/branch/develop/workflow-version.json"
|
||||
```
|
||||
|
||||
### 2. 버전 비교
|
||||
로컬 `.claude/workflow-version.json`과 비교:
|
||||
로컬 `.claude/workflow-version.json`의 `applied_global_version` 필드와 비교:
|
||||
- 버전 일치 → "최신 버전입니다" 안내 후 종료
|
||||
- 버전 불일치 → 미적용 변경 항목 추출하여 표시
|
||||
|
||||
@ -26,8 +26,19 @@ curl -sf "${GITEA_URL}/api/v1/repos/gc/template-common/raw/workflow-version.json
|
||||
1. `.claude/workflow-version.json`의 `project_type` 필드 확인
|
||||
2. 없으면: `pom.xml` → java-maven, `build.gradle` → java-gradle, `package.json` → react-ts
|
||||
|
||||
### Gitea 파일 다운로드 URL 패턴
|
||||
⚠️ Gitea raw 파일은 반드시 **web raw URL**을 사용해야 합니다 (`/api/v1/` 경로 사용 불가):
|
||||
```bash
|
||||
GITEA_URL="${GITEA_URL:-https://gitea.gc-si.dev}"
|
||||
# common 파일: ${GITEA_URL}/gc/template-common/raw/branch/develop/<파일경로>
|
||||
# 타입별 파일: ${GITEA_URL}/gc/template-<타입>/raw/branch/develop/<파일경로>
|
||||
# 예시:
|
||||
curl -sf "${GITEA_URL}/gc/template-common/raw/branch/develop/.claude/rules/team-policy.md"
|
||||
curl -sf "${GITEA_URL}/gc/template-react-ts/raw/branch/develop/.editorconfig"
|
||||
```
|
||||
|
||||
### 4. 파일 다운로드 및 적용
|
||||
Gitea API로 해당 타입 + common 템플릿 파일 다운로드:
|
||||
위의 URL 패턴으로 해당 타입 + common 템플릿 파일 다운로드:
|
||||
|
||||
#### 4-1. 규칙 파일 (덮어쓰기)
|
||||
팀 규칙은 로컬 수정 불가 — 항상 글로벌 최신으로 교체:
|
||||
@ -42,13 +53,17 @@ Gitea API로 해당 타입 + common 템플릿 파일 다운로드:
|
||||
#### 4-2. settings.json (부분 갱신)
|
||||
- `deny` 목록: 글로벌 최신으로 교체
|
||||
- `allow` 목록: 기존 사용자 커스텀 유지 + 글로벌 기본값 병합
|
||||
- `hooks`: 글로벌 최신으로 교체
|
||||
- `hooks`: init-project SKILL.md의 hooks JSON 블록을 참조하여 교체 (없으면 추가)
|
||||
- SessionStart(compact) → on-post-compact.sh
|
||||
- PreCompact → on-pre-compact.sh
|
||||
- PostToolUse(Bash) → on-commit.sh
|
||||
|
||||
#### 4-3. 스킬 파일 (덮어쓰기)
|
||||
```
|
||||
.claude/skills/create-mr/SKILL.md
|
||||
.claude/skills/fix-issue/SKILL.md
|
||||
.claude/skills/sync-team-workflow/SKILL.md
|
||||
.claude/skills/init-project/SKILL.md
|
||||
```
|
||||
|
||||
#### 4-4. Git Hooks (덮어쓰기 + 실행 권한)
|
||||
@ -56,13 +71,23 @@ Gitea API로 해당 타입 + common 템플릿 파일 다운로드:
|
||||
chmod +x .githooks/*
|
||||
```
|
||||
|
||||
#### 4-5. Hook 스크립트 갱신
|
||||
init-project SKILL.md의 코드 블록에서 최신 스크립트를 추출하여 덮어쓰기:
|
||||
```
|
||||
.claude/scripts/on-pre-compact.sh
|
||||
.claude/scripts/on-post-compact.sh
|
||||
.claude/scripts/on-commit.sh
|
||||
```
|
||||
실행 권한 부여: `chmod +x .claude/scripts/*.sh`
|
||||
|
||||
### 5. 로컬 버전 업데이트
|
||||
`.claude/workflow-version.json` 갱신:
|
||||
```json
|
||||
{
|
||||
"applied_global_version": "새버전",
|
||||
"applied_date": "오늘날짜",
|
||||
"project_type": "감지된타입"
|
||||
"project_type": "감지된타입",
|
||||
"gitea_url": "https://gitea.gc-si.dev"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"applied_global_version": "1.1.0",
|
||||
"applied_global_version": "1.2.0",
|
||||
"applied_date": "2026-02-14",
|
||||
"project_type": "java-maven",
|
||||
"gitea_url": "https://gitea.gc-si.dev"
|
||||
|
||||
@ -26,7 +26,7 @@ PATTERN='^(feat|fix|docs|style|refactor|test|chore|ci|perf)(\([a-zA-Z0-9가-힣.
|
||||
|
||||
FIRST_LINE=$(head -1 "$COMMIT_MSG_FILE")
|
||||
|
||||
if ! echo "$FIRST_LINE" | grep -qE "$PATTERN"; then
|
||||
if ! [[ "$FIRST_LINE" =~ $PATTERN ]]; then
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════════════════════════╗"
|
||||
echo "║ 커밋 메시지가 Conventional Commits 형식에 맞지 않습니다 ║"
|
||||
|
||||
불러오는 중...
Reference in New Issue
Block a user