Add release script and commit workflow docs
This commit is contained in:
+144
@@ -0,0 +1,144 @@
|
||||
# 提交与发版流程
|
||||
|
||||
本文档说明 EvoScientist 项目的代码提交、版本号管理与发版流程。
|
||||
|
||||
## 基本信息
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 远端仓库 | `https://git.foksai.com/ouyangbo/EvoScientist.git` |
|
||||
| 主开发分支 | `Ai4Sci` |
|
||||
| 版本号来源 | `EvoScientist/_version.py` (`__version__` 变量) |
|
||||
| `pyproject.toml` | 通过 `version = { attr = "EvoScientist._version.__version__" }` 动态读取 |
|
||||
| Tag 命名规则 | `v` + 版本号,如 `v0.1.20` ↔ `_version.py` 中的 `0.1.20` |
|
||||
|
||||
---
|
||||
|
||||
## 一、平时改代码(不发新版)
|
||||
|
||||
只是提交代码、版本号不变、**不打 tag**:
|
||||
|
||||
```bash
|
||||
git status # 查看改了什么
|
||||
git diff
|
||||
git add <文件> # 或 git add -A 全部暂存
|
||||
git commit -m "fix: 修复 xxx 问题" # 说明「为什么改」
|
||||
git push origin Ai4Sci
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、发新版本(手动 6 步)
|
||||
|
||||
以 `0.1.19 → 0.1.20` 为例。**顺序不能乱**:
|
||||
|
||||
```bash
|
||||
# 1. 改版本号 (只改 _version.py 一处)
|
||||
sed -i '' 's/__version__ = "0.1.19"/__version__ = "0.1.20"/' EvoScientist/_version.py
|
||||
|
||||
# 2. 验证改对
|
||||
grep version EvoScientist/_version.py # 应输出 __version__ = "0.1.20"
|
||||
|
||||
# 3. 提交版本号改动
|
||||
git add EvoScientist/_version.py
|
||||
git commit -m "Bump version to 0.1.20"
|
||||
|
||||
# 4. 打 tag (tag 名必须 = v + 版本号)
|
||||
git tag -a v0.1.20 -m "Release v0.1.20"
|
||||
|
||||
# 5. 推代码
|
||||
git push origin Ai4Sci
|
||||
|
||||
# 6. 推 tag
|
||||
git push origin v0.1.20
|
||||
```
|
||||
|
||||
### 版本号怎么选(SemVer)
|
||||
|
||||
| 改动类型 | 升级哪段 | 例子 |
|
||||
|---|---|---|
|
||||
| bug 修复、小调整 | patch(末位) | `0.1.19 → 0.1.20` |
|
||||
| 新增功能、向后兼容 | minor(中位) | `0.1.19 → 0.2.0` |
|
||||
| 破坏性改动 | major(首位) | `0.1.19 → 1.0.0` |
|
||||
|
||||
---
|
||||
|
||||
## 三、发新版本(自动,推荐)
|
||||
|
||||
用 `scripts/release.sh` 一条命令完成 bump + 提交 + tag + 推送:
|
||||
|
||||
```bash
|
||||
./scripts/release.sh patch # 0.1.19 → 0.1.20
|
||||
./scripts/release.sh minor # 0.1.19 → 0.2.0
|
||||
./scripts/release.sh major # 0.1.19 → 1.0.0
|
||||
```
|
||||
|
||||
**前置条件**:工作区必须干净(所有代码改动已提交)。脚本会自动检查,如果有未提交改动会拒绝运行。
|
||||
|
||||
### 典型发版流程
|
||||
|
||||
```bash
|
||||
# 1. 先提交代码改动
|
||||
git add -A
|
||||
git commit -m "feat: 新增 xxx 功能"
|
||||
git push origin Ai4Sci
|
||||
|
||||
# 2. 再发版
|
||||
./scripts/release.sh patch
|
||||
```
|
||||
|
||||
### 脚本内部做了什么
|
||||
|
||||
```
|
||||
读取 _version.py 当前版本 → 计算新版本 → sed 改写 → 验证 →
|
||||
git add _version.py → git commit → git tag → push 代码 → push tag
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、Tag 与 Release 的区别
|
||||
|
||||
| | Tag | Release |
|
||||
|---|---|---|
|
||||
| 本质 | git 自带的提交标记 | Gitea 的「发布」页面 |
|
||||
| 位置 | 仓库 → Commits → Tags 子标签 | 仓库首页 / Releases 标签 |
|
||||
| 显示 | 仅 tag 名 + 一句说明 | tag + 标题 + 详细说明 + 附件 |
|
||||
| 创建 | `git push origin v0.1.20` | 网页手动「New Release」或 API |
|
||||
|
||||
`release.sh` 推的是 **Tag**。如想在仓库首页显眼位置看到版本号,需另建 Release:
|
||||
|
||||
```bash
|
||||
# 需在网页生成 Access Token (勾选 write:repository)
|
||||
curl -X POST "https://git.foksai.com/api/v1/repos/ouyangbo/EvoScientist/releases" \
|
||||
-H "Authorization: token 你的TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"tag_name": "v0.1.20",
|
||||
"name": "v0.1.20",
|
||||
"body": "新增 xxx 功能",
|
||||
"target_commitish": "Ai4Sci"
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、常见问题
|
||||
|
||||
| 现象 | 原因 | 解决 |
|
||||
|---|---|---|
|
||||
| `git push` 被拒 `rejected` | 远端有本地没有的提交 | `git pull origin Ai4Sci --rebase` 再 push |
|
||||
| tag 推不上去 | tag 已存在于远端 | 换版本号,或删本地 `git tag -d v0.1.20` |
|
||||
| 改了版本号但 tag 名对不上 | 步骤 1 和 4 版本号不一致 | tag 名必须 `v` + 版本号 |
|
||||
| 推送要密码 | HTTPS 认证 | 用 Access Token 当密码,或改 SSH |
|
||||
| `release.sh` 报「工作区有未提交改动」 | 发版前没提交代码 | 先 `git commit` 代码改动,再跑脚本 |
|
||||
|
||||
---
|
||||
|
||||
## 六、速查清单
|
||||
|
||||
```
|
||||
平时: git add → git commit → git push
|
||||
发版: 先提交代码 → ./scripts/release.sh patch|minor|major
|
||||
手动发版: 改 _version.py → add → commit → tag → push 代码 → push tag
|
||||
纪律: tag 名 = v + _version.py 版本号,打 tag 前一定先提交版本号改动
|
||||
```
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bash
|
||||
# scripts/release.sh — 发版脚本: bump 版本号 → 提交 → 打 tag → 推送
|
||||
# 用法: ./scripts/release.sh patch|minor|major
|
||||
set -euo pipefail
|
||||
|
||||
VERSION_FILE="EvoScientist/_version.py"
|
||||
|
||||
# ── 参数检查 ──
|
||||
BUMP="${1:-}"
|
||||
if [[ -z "$BUMP" ]]; then
|
||||
cat <<USAGE
|
||||
用法: ./scripts/release.sh patch|minor|major
|
||||
|
||||
示例:
|
||||
./scripts/release.sh patch # 0.1.19 → 0.1.20 (bug 修复 / 小改动)
|
||||
./scripts/release.sh minor # 0.1.19 → 0.2.0 (新功能, 向后兼容)
|
||||
./scripts/release.sh major # 0.1.19 → 1.0.0 (破坏性改动)
|
||||
|
||||
发版前请先提交所有代码改动 (git status 应为空)。
|
||||
USAGE
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── 环境检查 ──
|
||||
[[ -f "$VERSION_FILE" ]] || { echo "✗ 找不到 $VERSION_FILE"; exit 1; }
|
||||
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { echo "✗ 不在 git 仓库内"; exit 1; }
|
||||
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
[[ "$BRANCH" != "HEAD" ]] || { echo "✗ 处于 detached HEAD, 请先切到分支"; exit 1; }
|
||||
|
||||
# 工作区必须干净 —— 发版提交只应包含版本号改动, 不混入其他代码
|
||||
if ! git diff --quiet || ! git diff --cached --quiet; then
|
||||
echo "✗ 工作区有未提交改动, 请先提交:"
|
||||
git status --short
|
||||
echo
|
||||
echo "提示: 先 git add + git commit 你的代码改动, 再运行本脚本。"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── 计算新版本号 ──
|
||||
current=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' "$VERSION_FILE" | head -1)
|
||||
[[ -n "$current" ]] || { echo "✗ $VERSION_FILE 里找不到版本号"; exit 1; }
|
||||
|
||||
IFS='.' read -r major minor patch <<< "$current"
|
||||
case "$BUMP" in
|
||||
major) major=$((major+1)); minor=0; patch=0 ;;
|
||||
minor) minor=$((minor+1)); patch=0 ;;
|
||||
patch) patch=$((patch+1)) ;;
|
||||
*) echo "✗ 无效参数: $BUMP (用 patch|minor|major)"; exit 1 ;;
|
||||
esac
|
||||
new="$major.$minor.$patch"
|
||||
|
||||
[[ "$current" != "$new" ]] || { echo "✗ 版本号没变 ($current)"; exit 1; }
|
||||
|
||||
echo "▶ $current → $new (分支: $BRANCH)"
|
||||
|
||||
# ── 改版本号 (兼容 macOS/Linux) ──
|
||||
if [[ "$(uname)" == "Darwin" ]]; then
|
||||
sed -i '' "s/__version__ = \"$current\"/__version__ = \"$new\"/" "$VERSION_FILE"
|
||||
else
|
||||
sed -i "s/__version__ = \"$current\"/__version__ = \"$new\"/" "$VERSION_FILE"
|
||||
fi
|
||||
grep -q "__version__ = \"$new\"" "$VERSION_FILE" || { echo "✗ 版本号替换失败, 检查 $VERSION_FILE 格式"; exit 1; }
|
||||
|
||||
# ── 提交 + 打 tag + 推送 ──
|
||||
git add "$VERSION_FILE"
|
||||
git commit -m "Bump version to $new" >/dev/null
|
||||
git tag -a "v$new" -m "Release v$new"
|
||||
git push origin "$BRANCH"
|
||||
git push origin "v$new"
|
||||
|
||||
echo
|
||||
echo "✓ 发布完成"
|
||||
echo " 版本: $new"
|
||||
echo " Tag: v$new"
|
||||
echo " 分支: $BRANCH"
|
||||
echo " 提交: $(git rev-parse --short HEAD)"
|
||||
Reference in New Issue
Block a user