# AiNiee-Next 快速发布指南

## 🎯 快速开始

这是发布AiNiee-Next到PyPI的简化版指南。完整分析请参考 [pip-publishing-analysis.md](pip-publishing-analysis.md)。

## 📋 发布前检查清单

### 必须完成
- [ ] 更新版本号（pyproject.toml和ainiee_cli.py）
- [ ] 更新CHANGELOG.md
- [ ] 确认所有测试通过
- [ ] 确认代码已提交到git

### 建议完成
- [ ] 优化Resource目录大小
- [ ] 放宽Python版本限制
- [ ] 完善项目元数据

## 🚀 发布步骤（简化版）

### 1. 准备环境

```bash
# 安装发布工具
pip install --upgrade build twine

# 或使用uv
uv pip install --upgrade build twine
```

### 2. 构建包

```bash
# 清理旧构建
rm -rf dist/ build/ *.egg-info

# 构建
python -m build

# 检查构建结果
ls -lh dist/
```

**预期输出**:
```
ainiee_cli-1.0.0-py3-none-any.whl
ainiee_cli-1.0.0.tar.gz
```

### 3. 检查包

```bash
# 检查元数据
twine check dist/*

# 查看wheel内容
unzip -l dist/ainiee_cli-1.0.0-py3-none-any.whl | head -50

# 查看tarball内容
tar -tzf dist/ainiee_cli-1.0.0.tar.gz | head -50
```

### 4. 本地测试

```bash
# 创建测试环境
python -m venv test-env
source test-env/bin/activate  # Linux/Mac
# test-env\Scripts\activate  # Windows

# 安装构建的包
pip install dist/ainiee_cli-1.0.0-py3-none-any.whl

# 测试
ainiee --help
ainiee --version

# 清理
deactivate
rm -rf test-env
```

### 5. 注册PyPI账户

1. 访问 https://pypi.org/account/register/
2. 注册并验证邮箱
3. 启用2FA（推荐）
4. 创建API token:
   - Account Settings → API tokens → Add API token
   - Scope: "Entire account"（首次发布）
   - 复制token（格式：`pypi-AgEIcHlwaS5vcmcCJD...`）

### 6. 配置凭证

**方法1: .pypirc文件（推荐）**

```bash
cat > ~/.pypirc << EOF
[distutils]
index-servers =
    pypi
    testpypi

[pypi]
username = __token__
password = pypi-YOUR_TOKEN_HERE

[testpypi]
username = __token__
password = pypi-YOUR_TEST_TOKEN_HERE
repository = https://test.pypi.org/legacy/
EOF

chmod 600 ~/.pypirc
```

**方法2: 环境变量**

```bash
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-YOUR_TOKEN_HERE
```

### 7. 发布到TestPyPI（强烈推荐）

```bash
# 上传到TestPyPI
twine upload --repository testpypi dist/*

# 从TestPyPI安装测试
pip install --index-url https://test.pypi.org/simple/ ainiee-cli

# 测试
ainiee --version
```

### 8. 发布到正式PyPI

```bash
# 确认一切正常后，发布到PyPI
twine upload dist/*

# 从PyPI安装测试
pip install ainiee-cli

# 测试
ainiee --version
```

### 9. 验证发布

访问 https://pypi.org/project/ainiee-cli/ 确认：
- [ ] 页面正确显示
- [ ] README渲染正确
- [ ] 版本号正确
- [ ] 下载链接可用

## 📦 完整发布脚本

创建 `scripts/publish.sh`:

```bash
#!/bin/bash
set -e

# 配置
VERSION=$(grep -m 1 version pyproject.toml | cut -d'"' -f2)
PACKAGE_NAME="ainiee-cli"

echo "🚀 Publishing ${PACKAGE_NAME} v${VERSION}"

# 检查是否在git根目录
if [ ! -f "pyproject.toml" ]; then
    echo "❌ Error: pyproject.toml not found. Please run from project root."
    exit 1
fi

# 检查git状态
if [ -n "$(git status --porcelain)" ]; then
    echo "❌ Error: Git working directory is not clean."
    echo "Please commit or stash your changes first."
    exit 1
fi

# 清理旧构建
echo "🧹 Cleaning old builds..."
rm -rf dist/ build/ *.egg-info

# 构建
echo "📦 Building package..."
python -m build

# 检查
echo "🔍 Checking package..."
twine check dist/*

# 询问发布目标
echo ""
echo "Where do you want to publish?"
echo "1) TestPyPI (recommended for testing)"
echo "2) PyPI (production)"
echo "3) Both"
echo "4) Cancel"
read -p "Enter choice [1-4]: " choice

case $choice in
    1)
        echo "🧪 Publishing to TestPyPI..."
        twine upload --repository testpypi dist/*
        echo "✅ Published to TestPyPI!"
        echo "Install with: pip install --index-url https://test.pypi.org/simple/ ${PACKAGE_NAME}"
        ;;
    2)
        echo "🌍 Publishing to PyPI..."
        read -p "Are you sure? This is PRODUCTION! [y/N]: " confirm
        if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
            twine upload dist/*
            echo "✅ Published to PyPI!"
            echo "Install with: pip install ${PACKAGE_NAME}"
            echo "View at: https://pypi.org/project/${PACKAGE_NAME}/"
        else
            echo "❌ Cancelled"
        fi
        ;;
    3)
        echo "🧪 Publishing to TestPyPI..."
        twine upload --repository testpypi dist/*
        echo "✅ Published to TestPyPI!"

        echo "🌍 Publishing to PyPI..."
        read -p "Are you sure? This is PRODUCTION! [y/N]: " confirm
        if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
            twine upload dist/*
            echo "✅ Published to PyPI!"
        fi
        ;;
    4)
        echo "❌ Cancelled"
        ;;
    *)
        echo "❌ Invalid choice"
        exit 1
        ;;
esac

echo ""
echo "🎉 Done!"
```

使用:
```bash
chmod +x scripts/publish.sh
./scripts/publish.sh
```

## 🔄 自动化发布（GitHub Actions）

### 创建GitHub Actions工作流

创建 `.github/workflows/publish.yml`:

```yaml
name: Publish to PyPI

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install build tools
        run: |
          python -m pip install --upgrade pip
          pip install build twine

      - name: Build package
        run: python -m build

      - name: Check package
        run: twine check dist/*

      - name: Publish to TestPyPI
        if: github.event.release.prerelease
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
        run: twine upload --repository testpypi dist/*

      - name: Publish to PyPI
        if: '!github.event.release.prerelease'
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
        run: twine upload dist/*
```

### 配置GitHub Secrets

1. 进入仓库 Settings → Secrets and variables → Actions
2. 添加secrets:
   - `PYPI_API_TOKEN`: PyPI的API token
   - `TEST_PYPI_API_TOKEN`: TestPyPI的API token

### 触发发布

```bash
# 创建GitHub Release，自动触发发布
gh release create v1.0.0 --title "v1.0.0" --notes "Release notes here"

# 或创建预发布（发布到TestPyPI）
gh release create v1.0.0rc1 --prerelease --title "v1.0.0rc1" --notes "Pre-release"
```

## ⚠️ 常见问题

### 1. 包太大

**问题**: Resource目录56MB导致包过大

**解决**:
```bash
# 临时方案：排除大型模型
# 在pyproject.toml中添加：
[tool.hatch.build.targets.wheel]
exclude = ["Resource/Models/**"]
```

### 2. 上传失败

**错误**: `403 Forbidden`

**原因**:
- API token无效
- 包名已被占用
- 版本号已存在

**解决**:
```bash
# 检查token
echo $TWINE_PASSWORD

# 检查包名是否已存在
pip search ainiee-cli  # 可能已禁用

# 确认版本号
grep version pyproject.toml
```

### 3. 依赖冲突

**错误**: 依赖安装失败

**解决**:
```bash
# 检查依赖
pip-compile requirements.txt

# 测试安装
pip install --dry-run dist/ainiee_cli-1.0.0-py3-none-any.whl
```

### 4. README不显示

**原因**: 格式问题

**解决**:
```bash
# 检查README格式
twine check dist/*

# 确保README.md存在且格式正确
python -m readme_renderer README.md
```

## 📊 版本更新流程

### 更新补丁版本 (1.0.0 → 1.0.1)

```bash
# 1. 更新版本号
# pyproject.toml: version = "1.0.1"
# ainiee_cli.py: __version__ = "1.0.1"

# 2. 更新CHANGELOG
# 添加v1.0.1的变更记录

# 3. 提交
git add -A
git commit -m "Bump version to 1.0.1"

# 4. 打标签
git tag v1.0.1

# 5. 推送
git push origin main --tags

# 6. 发布
./scripts/publish.sh
```

### 使用bump2version（推荐）

```bash
# 安装
pip install bump2version

# 配置 .bumpversion.cfg
[bumpversion]
current_version = 1.0.0
commit = True
tag = True

[bumpversion:file:pyproject.toml]
[bumpversion:file:ainiee_cli.py]

# 使用
bumpversion patch  # 1.0.0 → 1.0.1
bumpversion minor  # 1.0.1 → 1.1.0
bumpversion major  # 1.1.0 → 2.0.0
```

## 🎓 最佳实践

### 发布频率
- ✅ 小版本频繁发布（修复bug）
- ✅ 定期版本发布（新功能）
- ✅ 预发布版本测试（alpha, beta, rc）

### 版本命名
- `1.0.0` - 正式版本
- `1.0.0a1` - Alpha版本
- `1.0.0b1` - Beta版本
- `1.0.0rc1` - Release Candidate

### 发布清单
- [ ] 代码审查通过
- [ ] 测试全部通过
- [ ] 文档已更新
- [ ] CHANGELOG已更新
- [ ] 版本号已更新
- [ ] Git标签已创建
- [ ] 发布说明已准备

## 📚 参考资料

- [Python Packaging Guide](https://packaging.python.org/)
- [PyPI Help](https://pypi.org/help/)
- [Twine Documentation](https://twine.readthedocs.io/)
- [Hatch Documentation](https://hatch.pypa.io/)

## 🆘 获取帮助

- GitHub Issues: https://github.com/ShadowLoveElysia/AiNiee-Next/issues
- PyPI Support: https://pypi.org/help/
- Python Discord: https://discord.gg/python

---

**最后更新**: 2025-01-14
**适用版本**: AiNiee-Next v1.0.0+
