# sql5 v1.22 版本說明(已完成)
## 版本資訊
- **版本**:1.22
- **日期**:2026-05-04
- **名稱**:PyPI 打包
## 已實作功能
### Python Package (`sql5_pypi/`)
```
sql5_pypi/
├── sql5/ # Python package
│ ├── __init__.py # __version__
│ ├── __main__.py # CLI entry point
│ └── _binary.py # Binary download manager
├── pyproject.toml # PEP 517 構建設定
├── setup.cfg # 安裝設定
├── README.md
├── LICENSE (MIT)
└── .github/workflows/
├── release.yml # 建置 + 發布 PyPI
└── ci.yml # 測試 CI
```
## 發布流程
### 1. 設定 GitHub Secrets
在 GitHub Repository Settings → Secrets 新增:
- `PYPI_TOKEN` — PyPI API Token
### 2. 推送 Tag 觸發 Release
```bash
git tag v1.21.0
git push origin v1.21.0
```
### 3. GitHub Actions 自動執行
1. 為 4 個平台建置 binary(macos-arm64, macos-x86_64, linux-x86_64, windows-x86_64)
2. 上傳 binary 到 GitHub Release
3. 發布到 PyPI
### 4. pip install
```bash
pip install sql5
sql5 # 執行 REPL
sql5 database.db # 開啟資料庫
```
## Binary 下載時機
- `import sql5` — 不下載任何東西
- 第一次執行 `sql5` CLI — 自動下載對應平台的 binary 到 `~/.cache/sql5/`
## 目標
將 `sql5` 發布到 PyPI(`pip install sql5`),使用 **純 Python 包 + 預編譯 Binary** 方案。
## 套件結構
```
sql5-pypi/
├── sql5/ # Python package
│ ├── __init__.py # version, main CLI
│ ├── __main__.py # python -m sql5
│ └── _binary.py # 下載並管理 binary
├── pyproject.toml # PEP 517 構建設定
├── setup.cfg # 安裝設定
├── README.md
├── LICENSE
└── .github/
└── workflows/
└── release.yml # CI: 建置 + 發布 PyPI
```
## Binary 管理策略
### 下載時機
- `import sql5` 時不做任何事
- 第一次執行 `sql5` CLI 時,檢查並下載對應平台的 binary
### 版本對應
- PyPI version = Rust package version (e.g., v1.21.0 → 1.21.0)
- Binary 存在於 GitHub Release 的 asset
### 平台偵測
```python
import platform, sys
def get_platform():
system = platform.system().lower() # linux / darwin / windows
machine = platform.machine().lower() # x86_64 / arm64 / aarch64
if system == "darwin" and machine == "arm64":
return "macos-arm64"
elif system == "darwin":
return "macos-x86_64"
elif system == "linux":
return "linux-x86_64"
elif system == "windows":
return "windows-x86_64"
raise UnsupportedPlatform()
```
### Binary 路徑
```python
BINARY_NAME = {
"macos-arm64": "sql5-macos-arm64",
"macos-x86_64": "sql5-macos-x86_64",
"linux-x86_64": "sql5-linux-x86_64",
"windows-x86_64": "sql5-windows.exe",
}
VERSION = "1.21.0"
BASE_URL = f"https://github.com/{OWNER}/{REPO}/releases/download/v{VERSION}"
BINARY_URL = f"{BASE_URL}/{BINARY_NAME}"
```
## CI/CD 流程
### 觸發條件
- Push tag `v*.*.*` 到 GitHub
- 或手動 workflow_dispatch
### 步驟
1. **建置 Binary**(矩陣:linux-x86_64, macos-x86_64, macos-arm64, windows-x86_64)
- `cargo build --release`
- 輸出到 `target/release/sql5`
2. **命名 Asset**
- `sql5-{version}-{platform}.{ext}`
3. **上傳到 GitHub Release**
- 使用 `softprops/action-gh-release`
4. **發布到 PyPI**
- 使用 `pypa/gh-action-pypi-publish`
### GitHub Actions Workflow
```yaml
name: Release
on:
push:
tags: ['v*.*.*']
workflow_dispatch:
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
platform: linux-x86_64
- os: macos-latest
target: x86_64-apple-darwin
platform: macos-x86_64
- os: macos-latest
target: aarch64-apple-darwin
platform: macos-arm64
- os: windows-latest
target: x86_64-pc-windows-msvc
platform: windows-x86_64
publish:
needs: build
runs-on: ubuntu-latest
steps:
- uses: pypa/gh-action-pypi-publish@release/v1
```
## Python 包內容
### `sql5/__init__.py`
```python
__version__ = "1.21.0"
```
### `sql5/__main__.py`
```python
import sys, os
from sql5._binary import get_binary_path
def main():
binary = get_binary_path()
os.execv(binary, [binary] + sys.argv[1:])
if __name__ == "__main__":
main()
```
### `sql5/_binary.py`
```python
import os, sys, platform, hashlib, tempfile, subprocess, urllib.request
VERSION = "1.21.0"
OWNER = "你的GitHub用戶名"
REPO = "sql5"
BINARY_URLS = {
"linux-x86_64": f"https://github.com/{OWNER}/{REPO}/releases/download/v{VERSION}/sql5-linux-x86_64",
"macos-x86_64": f"https://github.com/{OWNER}/{REPO}/releases/download/v{VERSION}/sql5-macos-x86_64",
"macos-arm64": f"https://github.com/{OWNER}/{REPO}/releases/download/v{VERSION}/sql5-macos-arm64",
"windows-x86_64": f"https://github.com/{OWNER}/{REPO}/releases/download/v{VERSION}/sql5-windows.exe",
}
def get_platform():
system = platform.system().lower()
machine = platform.machine().lower()
if system == "darwin" and machine == "arm64":
return "macos-arm64"
elif system == "darwin":
return "macos-x86_64"
elif system == "linux":
return "linux-x86_64"
elif system == "windows":
return "windows-x86_64"
raise RuntimeError(f"Unsupported platform: {system}/{machine}")
def get_binary_path():
cache_dir = os.path.join(os.path.expanduser("~"), ".cache", "sql5")
os.makedirs(cache_dir, exist_ok=True)
platform_name = get_platform()
binary_name = {
"linux-x86_64": "sql5-linux-x86_64",
"macos-x86_64": "sql5-macos-x86_64",
"macos-arm64": "sql5-macos-arm64",
"windows-x86_64": "sql5-windows.exe",
}[platform_name]
binary_path = os.path.join(cache_dir, binary_name)
if not os.path.exists(binary_path):
url = BINARY_URLS[platform_name]
print(f"Downloading sql5 {VERSION} for {platform_name}...", file=sys.stderr)
urllib.request.urlretrieve(url, binary_path)
os.chmod(binary_path, 0o755)
return binary_path
```
## 預備工作
1. **建立 GitHub Repository**(如果還沒有)
2. **設定 PyPI Token**(GitHub Secrets: `PYPI_TOKEN`)
3. **設定 Cargo.toml 的 `edition`** — 確認 `edition = "2024"` Rust 2024 版需要 nightly
## 版本同步策略
- `Cargo.toml` version → PyPI version
- 在 CI 中從 `Cargo.toml` 讀取 version 並 tag release
## 限制與替代方案
| Cross-compile 到 Windows | 使用 `cargo-xwin` 或 GitHub Windows runner |
| ARM Linux | 可能需要 `cross` 或手動編譯 |
| PyPI 上傳需 API token | 使用 `pypa/gh-action-pypi-publish` |
## 待確認事項
1. GitHub Repository URL?
2. PyPI 帳號是否已申請?
3. 是否要支援 ARM Linux?
4. Binary 授權(MIT)?