diff --git a/docs/git 태그 작성 규칙.md b/docs/git 태그 작성 규칙.md new file mode 100644 index 0000000..e3b131e --- /dev/null +++ b/docs/git 태그 작성 규칙.md @@ -0,0 +1,86 @@ +# 🏷️ Git 태그 작성 및 통합 업데이트 관리 규칙 + +이 문서는 Smart IMS 플랫폼의 자동 업데이트 엔진이 인식하는 **Git 태그 작성 규칙**과 기본적인 **Git 명령어** 활용법을 설명합니다. 본 플랫폼은 Git 태그의 메시지를 자동으로 파싱하여 관리 페이지의 업데이트 히스토리를 생성합니다. + +--- + +## 1. 태그 메시지 작성 규칙 (Convention) + +플랫폼의 업데이트 엔진은 태그 메시지의 **머리말(Prefix)**과 **리스트 기호(`-`, `*`)**를 분석합니다. + +### 📋 메시지 구조 +```text +[TYPE] 업데이트 제목 (한 줄 요약) +- 상세 변경 내용 1 +- 상세 변경 내용 2 +* 상세 변경 내용 3 +``` + +### 🏷️ 업데이트 타입 (TYPE) 정의 +메시지 첫 줄에 아래 대괄호 키워드를 포함하면 관리 페이지에서 시각적으로 구분됩니다. + +| 키워드 | 업데이트 유형 | 시각적 표시 | 비고 | +|:--- |:--- |:--- |:--- | +| `[URGENT]` | **긴급/보안** | 빨간색 배너 | 최우선 업데이트 권장 | +| `[HOTFIX]` | **긴급 수정** | 빨간색 배너 | 버그 즉시 수정 건 | +| `[FEATURE]` | **기능 추가** | 남색(Indigo) | 새로운 기능 도입 | +| `[FIX]` | **일반 수정** | 회색(Slate) | 일반적인 버그 수정 | +| `[PATCH]` | **패치/보정** | 회색(Slate) | 마이너 품질 개선 | + +--- + +## 2. 릴리즈 배포 절차 (명령어) + +새로운 버전을 배포할 때는 아래 순서대로 명령어를 실행합니다. + +### STEP 1: 코드 변경 사항 커밋 +```powershell +git add . +git commit -m "커밋 메시지 (태그와 별개)" +git push origin main +``` + +### STEP 2: 어노테이티드 태그(Annotated Tag) 생성 +시스템 엔진이 메시지를 읽으려면 반드시 `-a` 옵션을 사용하는 **Annotated Tag**여야 합니다. + +```powershell +# 예시: v0.3.5 버전 배포 시 +git tag -a v0.3.5 -m "[FEATURE] 보고서 출력 기능 도입 +- 자산 상세 페이지 PDF 저장 기능 추가 +- 정비 이력 엑셀 내보내기 필터 보강 +- 인쇄용 스타일 시트 최적화" +``` + +### STEP 3: 원격 저장소에 태그 푸시 +```powershell +# 특정 태그만 푸시 +git push origin v0.3.5 + +# 생성된 모든 로컬 태그 푸시 +git push origin --tags +``` + +--- + +## 3. 유용한 Git 명령어 레퍼런스 + +### 🔍 조회 관련 +* **태그 목록 확인**: `git tag -l` +* **특정 태그의 상세 메시지 확인**: `git show v0.3.5` +* **최신 태그 정보 확인**: `git describe --tags --abbrev=0` + +### 🛠️ 관리 관련 +* **태그 삭제 (로컬)**: `git tag -d v0.3.5` +* **태그 삭제 (원격)**: `git push origin :refs/tags/v0.3.5` +* **실수로 태그 메시지를 잘못 적었을 때 (수정)**: + ```powershell + git tag -a v0.3.5 -f -m "[FIX] 수정된 메시지 내용..." + git push origin v0.3.5 -f + ``` + +--- + +## 💡 주의사항 +1. **버전 넘버링**: `v0.0.0` 형식을 권장합니다 (예: `v0.3.4`). +2. **No-Cache**: 태그 푸시 후 관리 페이지에서 즉시 확인되지 않는 경우, 페이지 상단의 '새로고침' 아이콘을 눌러 원격 저장소와 동기화하세요. +3. **내용 입력**: `-` 또는 `*` 기호를 생략하면 해당 줄은 개별 리스트 항목으로 인식되지 않고 뭉쳐서 표시될 수 있습니다. diff --git a/package.json b/package.json index ecd6613..9c16bcf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "smartims", "private": true, - "version": "0.3.3", + "version": "0.3.5", "type": "module", "scripts": { "dev": "vite", diff --git a/server/package.json b/server/package.json index 984c141..ebcaa92 100644 --- a/server/package.json +++ b/server/package.json @@ -1,6 +1,6 @@ { "name": "server", - "version": "0.3.3", + "version": "0.3.5", "description": "", "main": "index.js", "scripts": { diff --git a/server/routes/system.js b/server/routes/system.js index 8640a53..1507f41 100644 --- a/server/routes/system.js +++ b/server/routes/system.js @@ -475,9 +475,10 @@ router.get('/version/remote', isAuthenticated, hasRole('admin'), async (req, res if (auth.user && auth.pass) { const authenticatedUrl = auth.url.replace('https://', `https://${encodeURIComponent(auth.user)}:${encodeURIComponent(auth.pass)}@`); - fetchCmd = `git fetch ${authenticatedUrl} --tags --force`; + // Use explicit refspec to ensure local tags are updated from the remote URL + fetchCmd = `git fetch ${authenticatedUrl} +refs/tags/*:refs/tags/* --force --prune --prune-tags`; } else { - fetchCmd = `git fetch ${auth.url} --tags --force`; + fetchCmd = `git fetch ${auth.url} +refs/tags/*:refs/tags/* --force --prune --prune-tags`; } exec(fetchCmd, (err, stdout, stderr) => { @@ -492,8 +493,8 @@ router.get('/version/remote', isAuthenticated, hasRole('admin'), async (req, res }); } - // Get last 10 tags with their annotation messages and dates - // Format: tag|subject|body|date + // Also ensure we are looking at the remote tags directly if possible for the 'latest' check + // but for history we still use the fetched local tags const format = '%(refname:short)|%(contents:subject)|%(contents:body)|%(creatordate:iso8601)'; const historyCmd = `git for-each-ref refs/tags --sort=-creatordate --format="${format}" --count=10`; diff --git a/src/platform/pages/VersionPage.tsx b/src/platform/pages/VersionPage.tsx index d41bf83..fd432b7 100644 --- a/src/platform/pages/VersionPage.tsx +++ b/src/platform/pages/VersionPage.tsx @@ -53,7 +53,7 @@ export function VersionPage() { const fetchRemoteVersion = async () => { setCheckingRemote(true); try { - const res = await apiClient.get('/system/version/remote'); + const res = await apiClient.get(`/system/version/remote?t=${Date.now()}`); setRemoteInfo(res.data); } catch (err) { console.error('Failed to fetch remote version info', err); @@ -110,7 +110,7 @@ export function VersionPage() { }; // Client/Frontend version fixed at build time - const frontendVersion = '0.3.3'; + const frontendVersion = '0.3.5'; const buildDate = '2026-01-24'; // Check if update is needed based on frontend version vs remote tag