# Hướng Dẫn Publish NPM Package

Tài liệu này hướng dẫn cách sử dụng script publish cho `@momo-kits/native-kits`.

---

## 📋 Tổng Quan

Dự án sử dụng **`publish.sh`** - một script thống nhất hỗ trợ 2 modes:

- **`beta`**: Publish phiên bản beta/alpha cho testing
- **`release`**: Publish phiên bản release chính thức

Script có 3 phases riêng biệt:
1. **Check Version**: Kiểm tra và chuẩn bị version
2. **Publish Maven**: Publish lên GitLab Maven repository
3. **Publish NPM**: Publish lên NPM registry

---

## 🚀 Publish Từ Local

### Yêu Cầu Trước Khi Publish

1. **Login NPM:**
   ```bash
   npm login
   ```

2. **Kiểm tra version hiện tại:**
   ```bash
   cat package.json | grep version
   ```

### 🔵 Publish Beta Từ Local

#### **Cách 1: Publish tất cả phases (Khuyến nghị)**

```bash
sh publish.sh beta
```

#### **Cách 2: Chạy từng phase riêng**

```bash
# Phase 1: Check version
sh publish.sh beta check

# Phase 2: Publish Maven
sh publish.sh beta maven

# Phase 3: Publish NPM
sh publish.sh beta npm
```

#### **Quy Trình Beta Publishing**

1. **Update version trong `package.json`:**
   ```json
   {
     "version": "0.156.2"
   }
   ```

2. **Chạy check version trước (optional nhưng khuyến nghị):**
   ```bash
   sh publish.sh beta check
   ```

3. **Nếu check thành công, publish:**
   ```bash
   sh publish.sh beta
   ```

---

## 📦 Version Types (Beta Mode)

Beta mode hỗ trợ 2 loại version:

### **1. Specific Version (Tag: alpha)**

**Định nghĩa:** Version có suffix KHÔNG phải "beta"

**Ví dụ:**
- `0.156.2-test.1`
- `0.156.2-alpha.1`
- `0.156.2-rc.1`

**Behavior:**
- NPM tag: `alpha`
- Check existence: ❌ **FAIL** nếu version đã tồn tại
- Không auto-increment
- Developer phải tự quản lý version

**Use case:** Testing specific features, hotfix testing

### **2. Normal Version (Tag: beta)**

**Định nghĩa:** Version có suffix "beta" HOẶC không có suffix

**Ví dụ:**
- `0.156.2` (no suffix)
- `0.156.2-beta.1`
- `0.156.2-beta.5`

**Behavior:**
- NPM tag: `beta`
- Auto-format: `0.156.2` → `0.156.2-beta.1`
- Auto-increment nếu tồn tại: `.beta.1` → `.beta.2` → `.beta.3`...

**Use case:** Regular beta testing, continuous development

---

## 🔍 Version Detection Examples

### **Example 1: Specific Version**

```bash
# package.json
{
  "version": "0.156.2-test.1"
}

# Run
$ sh publish.sh beta check

# Output
🏷️  Detected: SPECIFIC version (tag: alpha)
🔎 Checking if specific version 0.156.2-test.1 exists on npm...
✅ Specific version 0.156.2-test.1 does not exist on npm. Safe to publish.
✅ NPM tag: alpha
```

**Kết quả trên NPM:**
- `@momo-kits/native-kits@0.156.2-test.1` (tag: **alpha**)
- `@momo-kits/native-kits@0.156.2-test.1-debug` (tag: **alpha**)

### **Example 2: Normal Version (No Suffix)**

```bash
# package.json
{
  "version": "0.156.2"
}

# Run
$ sh publish.sh beta check

# Output
🏷️  Detected: NORMAL version (tag: beta)
🔄 Adding beta suffix: 0.156.2 → 0.156.2-beta.1
🔎 Checking version 0.156.2-beta.1 on npm...
✅ Version 0.156.2-beta.1 does not exist on npm. Using this version.
✅ NPM tag: beta
```

**Kết quả trên NPM:**
- `@momo-kits/native-kits@0.156.2-beta.1` (tag: **beta**)
- `@momo-kits/native-kits@0.156.2-beta.1-debug` (tag: **beta**)

### **Example 3: Normal Version (With Beta Suffix)**

```bash
# package.json
{
  "version": "0.156.2-beta.1"
}

# Giả sử npm đã có: beta.1, beta.2

# Run
$ sh publish.sh beta check

# Output
🏷️  Detected: NORMAL version (tag: beta)
🔎 Checking version 0.156.2-beta.1 on npm...
⚠️  Version 0.156.2-beta.1 already exists on npm. Auto-incrementing...
   Version incremented: 0.156.2-beta.1 → 0.156.2-beta.2
⚠️  Version 0.156.2-beta.2 already exists on npm. Auto-incrementing...
   Version incremented: 0.156.2-beta.2 → 0.156.2-beta.3
✅ Version 0.156.2-beta.3 does not exist on npm. Using this version.
✅ NPM tag: beta
```

**Kết quả trên NPM:**
- `@momo-kits/native-kits@0.156.2-beta.3` (tag: **beta**)
- `@momo-kits/native-kits@0.156.2-beta.3-debug` (tag: **beta**)

### **Example 4: Specific Version Already Exists (FAIL)**

```bash
# package.json
{
  "version": "0.156.2-test.1"
}

# Version đã tồn tại trên npm

# Run
$ sh publish.sh beta check

# Output
🏷️  Detected: SPECIFIC version (tag: alpha)
🔎 Checking if specific version 0.156.2-test.1 exists on npm...

❌ ERROR: Specific version 0.156.2-test.1 already exists on npm!

Please update the version in package.json before publishing.
# Exit code: 1
```

---

## 🟢 Publish Release Từ Local

### **Đặc Điểm Quan Trọng**

⚠️ **Release mode KHÔNG đọc version từ `package.json`**

✅ **Release mode đọc version từ `npm@latest`**

### **Cách Publish**

```bash
# Publish tất cả phases
sh publish.sh release

# Hoặc từng phase
sh publish.sh release check
sh publish.sh release maven
sh publish.sh release npm
```

### **Quy Trình Release Publishing**

1. **Script đọc version từ npm@latest:**
   ```bash
   npm view @momo-kits/native-kits@latest version
   # Output: 0.156.2
   ```

2. **Auto-increment patch version:**
   ```
   0.156.2 → 0.156.3
   ```

3. **Check existence và tiếp tục increment nếu cần:**
   ```
   0.156.3 exists? → 0.156.4
   0.156.4 exists? → 0.156.5
   ...
   ```

4. **Update `package.json` với version mới**

5. **Publish với tag `latest`**

### **Example: Release Publishing**

```bash
$ sh publish.sh release check

# Output
🔍 Reading latest version from npm@latest (NOT from package.json)...
📦 Current @latest version on npm: 0.156.2
🔼 Auto-incremented version: 0.156.2 → 0.156.3
🔎 Checking if version 0.156.3 exists on npm...
✅ Version 0.156.3 does not exist on npm. Using this version.
📝 Updated package.json: 0.156.2-beta.5 → 0.156.3
✅ Using version: 0.156.3
✅ NPM tag: latest
```

**Kết quả trên NPM:**
- `@momo-kits/native-kits@0.156.3` (tag: **latest**)
- `@momo-kits/native-kits@0.156.3-debug` (tag: **latest**)

---

## 🤖 Publish Tự Động Trên GitLab CI

### 🔵 Beta Publishing (GitLab CI)

**Trigger:** Commit message chứa `[ci build]` (KHÔNG trên nhánh `main`)

```bash
git checkout develop
git add .
git commit -m "feat: add new feature [ci build]"
git push
```

**Pipeline sẽ chạy 3 stages:**
1. `beta_check_version` (Phase 1)
2. `beta_publish_maven` (Phase 2)
3. `beta_publish_npm` (Phase 3)

### 🟢 Release Publishing (GitLab CI)

**Trigger:** Push vào nhánh `main`

```bash
git checkout main
git merge develop
git push origin main
```

**Pipeline sẽ chạy 3 stages:**
1. `release_check_version` (Phase 1)
2. `release_publish_maven` (Phase 2)
3. `release_publish_npm` (Phase 3)

---

## 📊 So Sánh Beta vs Release

| Tiêu chí | Beta Mode | Release Mode |
|----------|-----------|--------------|
| **Script** | `sh publish.sh beta` | `sh publish.sh release` |
| **Trigger CI** | Commit có `[ci build]` (không trên main) | Push vào `main` |
| **Read Version** | Từ `package.json` | Từ `npm@latest` |
| **Version Types** | Specific (alpha) / Normal (beta) | N/A |
| **NPM Tag** | `alpha` hoặc `beta` | `latest` |
| **If Exists** | Specific: FAIL / Normal: Auto-increment | Auto-increment |
| **Phase Order** | Check → Maven → NPM | Check → Maven → NPM |

---

## 🔧 NPM Tags Explained

### **Tag: alpha**

**Khi nào:** Beta mode + Specific version

**Cài đặt:**
```bash
npm install @momo-kits/native-kits@alpha
npm install @momo-kits/native-kits@0.156.2-test.1
```

**Use case:** Testing specific features, experimental builds

### **Tag: beta**

**Khi nào:** Beta mode + Normal version

**Cài đặt:**
```bash
npm install @momo-kits/native-kits@beta
npm install @momo-kits/native-kits@0.156.2-beta.1
```

**Use case:** Regular beta testing, pre-release versions

### **Tag: latest**

**Khi nào:** Release mode

**Cài đặt:**
```bash
npm install @momo-kits/native-kits@latest
npm install @momo-kits/native-kits
npm install @momo-kits/native-kits@0.156.3
```

**Use case:** Production releases, stable versions

---

## 🔍 Chi Tiết Các Phases

### **Phase 1: Check Version**

**Beta Mode:**
1. Đọc version từ `package.json`
2. Phát hiện version type (specific vs normal)
3. Set NPM tag (alpha vs beta)
4. Format version:
   - Specific: Check existence, fail if exists
   - Normal: Add beta suffix, auto-increment if exists
5. Update `gradle.properties`

**Release Mode:**
1. Đọc version từ `npm@latest` (KHÔNG từ package.json)
2. Increment patch version
3. Check existence, auto-increment if exists
4. Update `package.json` và `gradle.properties`
5. Set NPM tag = `latest`

### **Phase 2: Publish Maven**

**Thứ tự:** Chạy SAU phase 1, TRƯỚC phase 3

**Hành động:**
- Publish Kotlin Multiplatform artifacts
- Lên GitLab Packages Repository
- Dành cho `compose` module

### **Phase 3: Publish NPM**

**Thứ tự:** Chạy SAU phase 2 (Maven)

**Publish 2 versions theo thứ tự:**

1. **Debug version** (với compose) - FIRST
   - Version: `X.Y.Z-debug`
   - Bao gồm thư mục `compose/`
   - Tag: `alpha` / `beta` / `latest`

2. **Normal version** (không compose) - SECOND
   - Version: `X.Y.Z`
   - Không bao gồm `compose/`
   - Tag: `alpha` / `beta` / `latest`

---

## 🎯 Workflow Khuyến Nghị

### Development Flow

```
┌──────────────────────────────────────────────────┐
│ 1. Develop Feature                               │
│    - Code changes                                │
│    - Update version in package.json (beta only)  │
└─────────────────┬────────────────────────────────┘
                  ↓
┌──────────────────────────────────────────────────┐
│ 2. Beta Testing                                  │
│    Local: sh publish.sh beta                     │
│    CI: git commit -m "feat: xxx [ci build]"      │
│    Tag: alpha (specific) or beta (normal)        │
└─────────────────┬────────────────────────────────┘
                  ↓
┌──────────────────────────────────────────────────┐
│ 3. Team Testing                                  │
│    npm install @momo-kits/native-kits@beta       │
│    npm install @momo-kits/native-kits@alpha      │
└─────────────────┬────────────────────────────────┘
                  │
           ┌──────┴──────┐
           │  Approved?   │
           └──────┬───────┘
                  │ Yes
                  ↓
┌──────────────────────────────────────────────────┐
│ 4. Release Production                            │
│    Local: sh publish.sh release                  │
│    CI: merge to main                             │
│    Reads from npm@latest, auto-increment         │
└─────────────────┬────────────────────────────────┘
                  ↓
┌──────────────────────────────────────────────────┐
│ 5. Production                                    │
│    npm install @momo-kits/native-kits@latest     │
└──────────────────────────────────────────────────┘
```

---

## ⚠️ Lưu Ý Quan Trọng

### 1. Version Management

**Beta Mode:**
- Specific version: Phải unique, fail nếu tồn tại
- Normal version: Auto-increment, không cần lo
- Version trong `package.json` được sử dụng

**Release Mode:**
- ⚠️ **KHÔNG đọc từ `package.json`**
- ✅ **Đọc từ `npm@latest`**
- Auto-increment patch version
- `package.json` được UPDATE với version mới

### 2. NPM Tags

**Cài đặt theo tag:**
```bash
npm install @momo-kits/native-kits@alpha    # Specific versions
npm install @momo-kits/native-kits@beta     # Normal beta versions
npm install @momo-kits/native-kits@latest   # Release versions
```

### 3. Phase Execution Order

**Cả Beta và Release:**
1. Check Version
2. ✅ **Publish Maven** (FIRST)
3. ✅ **Publish NPM** (SECOND)

**Lý do:** Maven artifacts cần được publish trước để NPM debug version có thể reference

### 4. File Modifications

Script tạm thời modify các file (restore sau publish):
- `package.json` (version)
- `gradle.properties` (version)
- `.npmignore` (cho debug version)
- `compose/build.gradle.kts` (cho debug version)

---

## 🐛 Troubleshooting

### Lỗi: "Specific version already exists on npm"

**Nguyên nhân:** Specific version đã được publish

**Giải pháp:**
```bash
# Option 1: Tăng version thủ công
vim package.json
# "version": "0.156.2-test.1" → "0.156.2-test.2"

# Option 2: Chuyển sang normal version
vim package.json
# "version": "0.156.2-test.1" → "0.156.2"
# Script sẽ auto-format thành 0.156.2-beta.1
```

### Lỗi: "Could not read version from npm@latest"

**Nguyên nhân:** Package chưa tồn tại trên npm hoặc chưa có version @latest

**Giải pháp:**
```bash
# Kiểm tra package trên npm
npm view @momo-kits/native-kits

# Nếu chưa có, publish beta trước
sh publish.sh beta
```

### Beta không trigger trên GitLab CI

**Kiểm tra:**
- ✅ Commit message có `[ci build]`
- ✅ Branch KHÔNG phải `main`
- ✅ Branch KHÔNG match `engine/w*`

### Release không trigger trên GitLab CI

**Kiểm tra:**
- ✅ Đang push vào `main` branch
- ✅ GitLab CI settings enabled

---

## 📦 Sử Dụng Packages

### Cài Đặt Beta/Alpha Versions

```bash
# Latest alpha (specific versions)
npm install @momo-kits/native-kits@alpha

# Latest beta (normal versions)
npm install @momo-kits/native-kits@beta

# Specific version
npm install @momo-kits/native-kits@0.156.2-beta.1
npm install @momo-kits/native-kits@0.156.2-test.1

# Debug version (with compose)
npm install @momo-kits/native-kits@0.156.2-beta.1-debug
```

### Cài Đặt Release Versions

```bash
# Latest release
npm install @momo-kits/native-kits@latest
# hoặc
npm install @momo-kits/native-kits

# Specific release version
npm install @momo-kits/native-kits@0.156.3
```

---

## 🎓 Best Practices

### 1. Beta Testing

**Specific versions (alpha tag):**
- Dùng cho testing features cụ thể
- Phải unique, không duplicate
- Ví dụ: `0.156.2-hotfix.1`, `0.156.2-experiment.1`

**Normal versions (beta tag):**
- Dùng cho continuous development
- Auto-increment, dễ quản lý
- Ví dụ: `0.156.2`, `0.156.2-beta.1`

### 2. Release

- Luôn merge vào `main` để trigger release
- Không cần lo version trong `package.json`
- Script tự động đọc từ npm@latest và increment

### 3. Version Naming

**Good:**
- `0.156.2-test.1` (specific, clear purpose)
- `0.156.2-beta.1` (normal, standard format)
- `0.156.2` (normal, will auto-format)

**Avoid:**
- `0.156.2-beta-test.1` (confusing)
- `0.156.2-v1` (unclear)

---

## 📞 Support

Nếu có vấn đề, liên hệ team hoặc tạo issue trên GitLab.

---

## 🔗 Quick Reference

```bash
# Beta - Local (Specific version → alpha tag)
# package.json: "version": "0.156.2-test.1"
sh publish.sh beta

# Beta - Local (Normal version → beta tag)
# package.json: "version": "0.156.2"
sh publish.sh beta

# Release - Local (reads from npm@latest)
sh publish.sh release

# Individual phases
sh publish.sh beta check              # Phase 1
sh publish.sh beta maven              # Phase 2
sh publish.sh beta npm                # Phase 3

# Beta - CI
git commit -m "feat: xxx [ci build]"  # Trigger beta (not on main)

# Release - CI
git push origin main                  # Trigger release
```

---

## 📋 Version Type Decision Tree

```
Start: Publish Beta
    ↓
Check version in package.json
    ↓
Has suffix? (contains "-")
    ├─ No → Normal Version
    │         ├─ Auto-add: 0.156.2 → 0.156.2-beta.1
    │         ├─ Tag: beta
    │         └─ Auto-increment if exists
    │
    └─ Yes → Check suffix type
              ├─ Contains "beta" → Normal Version
              │                     ├─ Keep format: 0.156.2-beta.1
              │                     ├─ Tag: beta
              │                     └─ Auto-increment if exists
              │
              └─ Other suffix → Specific Version
                                ├─ Keep format: 0.156.2-test.1
                                ├─ Tag: alpha
                                └─ FAIL if exists
```
