🎨 代码格式化
Hello from ImmortalWrt / say-hello (push) Successful in 0s

:fix: 修复识别`CHANGELOG`标题问题
This commit is contained in:
csh
2025-11-02 23:13:48 +08:00
parent 84e2751668
commit ec5785cc6a
2 changed files with 116 additions and 88 deletions
+74 -46
View File
@@ -80,11 +80,11 @@ env:
# 需要忽略的提交模式(支持正则表达式)
# 这些提交不会被添加到 CHANGELOG 中
# 使用 | 分隔多个模式
#
#
# ⚠️ 重要说明:
# - 使用 ^ 表示行首匹配,$ 表示行尾匹配
# - [skip ci] 和 [ci skip] 仅匹配行尾,避免误过滤其他提交
# - 如果要完全匹配某个字符串,使用 ^...$
# - 如果要完全匹配某个字符串,使用 ^...$
IGNORE_PATTERNS: >-
^Merge |
^:memo: Auto update CHANGELOG|
@@ -226,21 +226,21 @@ jobs:
# 检查仓库状态
if [ -d "$REPO_DIR" ]; then
echo "📂 目录已存在,检查 Git 仓库状态..."
if [ -d "$REPO_DIR/.git" ]; then
# 目录存在且是有效的 Git 仓库
echo "✓ 发现有效的 Git 仓库,执行增量更新..."
cd "$REPO_DIR"
# 清理工作区
git clean -fdx
git reset --hard
# 获取最新代码和标签,同时清理远程已删除的 tag
echo "📥 拉取最新代码和标签..."
git fetch --all --tags --force --prune --prune-tags
echo "✓ 已同步远程状态(包括已删除的 tag)"
echo "✓ 仓库已更新"
else
# 目录存在但不是 Git 仓库(可能之前运行失败)
@@ -248,20 +248,20 @@ jobs:
echo "🧹 清理损坏的目录..."
rm -rf "$REPO_DIR"
echo "✓ 已清理"
# 重新克隆
echo "📥 克隆仓库..."
mkdir -p "${{ env.WORKSPACE_DIR }}"
git clone \
https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git \
"$REPO_DIR"
if [ $? -ne 0 ]; then
echo "❌ 克隆失败"
exit 1
fi
cd "$REPO_DIR"
echo "✓ 仓库已克隆"
fi
@@ -269,11 +269,11 @@ jobs:
# 目录不存在,首次克隆
echo "📥 克隆仓库(首次)..."
mkdir -p "${{ env.WORKSPACE_DIR }}"
git clone \
https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git \
"$REPO_DIR"
if [ $? -eq 0 ]; then
cd "$REPO_DIR"
echo "✓ 仓库已克隆"
@@ -362,7 +362,7 @@ jobs:
else
CHANGELOG_VERSION="${{ env.CHANGELOG_VERSION }}"
echo "📝 检查版本: $CHANGELOG_VERSION"
if grep -q "## :bookmark: $CHANGELOG_VERSION" CHANGELOG.md; then
echo "⚠️ 版本 $CHANGELOG_VERSION 已存在于 CHANGELOG.md"
echo "version_exists=true" >> $GITHUB_OUTPUT
@@ -395,23 +395,23 @@ jobs:
# 查找前一个 tag
# 排除所有属于当前 CHANGELOG 版本的 tag(例如 0.0.2-rc1, 0.0.2-rc2 都属于 0.0.2
echo "🔍 查找前一个版本的 tag..."
# 获取所有 tag
ALL_TAGS=$(git tag --sort=-version:refname)
# 遍历查找第一个不属于当前 CHANGELOG 版本的 tag
PREVIOUS_TAG=""
while IFS= read -r tag; do
# 跳过空行
[ -z "$tag" ] && continue
# 对每个 tag 执行 strip 操作(去除 pre-release 后缀)
if [[ "${{ env.CHANGELOG_VERSION_MODE }}" == "strip" ]]; then
tag_stripped=$(echo "$tag" | sed -E 's/-(alpha|beta|rc|pre|preview|dev|test)[0-9]*$//')
else
tag_stripped="$tag"
fi
# 如果这个 tag 的 CHANGELOG 版本不等于当前版本,就是我们要找的
if [ "$tag_stripped" != "$CHANGELOG_VERSION" ]; then
PREVIOUS_TAG="$tag"
@@ -424,13 +424,13 @@ jobs:
COMMIT_RANGE=""
else
echo "📍 Previous tag: $PREVIOUS_TAG"
# 对 previous tag 也执行 strip,显示对应的 CHANGELOG 版本
if [[ "${{ env.CHANGELOG_VERSION_MODE }}" == "strip" ]]; then
PREV_CHANGELOG_VERSION=$(echo "$PREVIOUS_TAG" | sed -E 's/-(alpha|beta|rc|pre|preview|dev|test)[0-9]*$//')
echo " (对应 CHANGELOG 版本: $PREV_CHANGELOG_VERSION)"
fi
COMMIT_RANGE="${PREVIOUS_TAG}..${VERSION}"
fi
@@ -477,9 +477,9 @@ jobs:
line = line.strip()
if not line or '|' not in line:
continue
commit_hash, message = line.split('|', 1)
# 检查是否应该忽略
should_ignore = False
matched_pattern = None
@@ -488,7 +488,7 @@ jobs:
should_ignore = True
matched_pattern = pattern
break
if should_ignore:
skipped_commits.append((message, matched_pattern))
else:
@@ -549,11 +549,11 @@ jobs:
# 找到版本区块,在其中追加新的提交
pattern = rf'(## :bookmark: {re.escape(changelog_version)}.*?\n{re.escape(section_title)}\n\n)(.*?)(\n---|\n## :bookmark: |\Z)'
match = re.search(pattern, existing_content, re.DOTALL)
if match:
existing_commits = match.group(2).strip()
new_commits = changelog_content.split(f"{section_title}\n\n")[1].split("\n---")[0].strip()
# 合并提交,去重
all_commits_text = existing_commits + "\n" + new_commits
# 简单去重(基于完整行)
@@ -563,36 +563,64 @@ jobs:
if line.strip() and line not in seen:
unique_lines.append(line)
seen.add(line)
merged_commits = '\n'.join(unique_lines)
# 重新组装版本区块
updated_section = match.group(1) + merged_commits + "\n\n---\n"
new_content = existing_content[:match.start()] + updated_section + existing_content[match.end():]
else:
print("⚠️ Could not find version section, prepending new content")
new_content = existing_content.replace(
"# :memo: CHANGELOG\n\n",
f"# :memo: CHANGELOG\n\n{changelog_content}"
)
# 尝试匹配各种可能的 CHANGELOG 标题格式
header_pattern = r'^#\s*(?::[\w_]+:)?\s*CHANGELOG\s*\n'
match = re.search(header_pattern, existing_content, re.IGNORECASE | re.MULTILINE)
if match:
insert_pos = match.end()
if not existing_content[insert_pos:insert_pos+1] == '\n':
new_content = existing_content[:insert_pos] + '\n' + changelog_content + existing_content[insert_pos:]
else:
new_content = existing_content[:insert_pos] + '\n' + changelog_content + existing_content[insert_pos+1:]
else:
# 没有找到标题,在开头插入
new_content = f"# :memo: CHANGELOG\n\n{changelog_content}{existing_content}"
else:
# 插入新版本
new_content = existing_content.replace(
"# :memo: CHANGELOG\n\n",
f"# :memo: CHANGELOG\n\n{changelog_content}"
)
# 尝试匹配各种可能的 CHANGELOG 标题格式
# 支持: # CHANGELOG, # :memo: CHANGELOG, # Changelog 等
# 尝试找到 CHANGELOG 标题(不区分大小写,可选 emoji)
header_pattern = r'^#\s*(?::[\w_]+:)?\s*CHANGELOG\s*\n'
match = re.search(header_pattern, existing_content, re.IGNORECASE | re.MULTILINE)
if match:
# 找到了 CHANGELOG 标题,在其后插入
insert_pos = match.end()
# 确保标题后有空行
if not existing_content[insert_pos:insert_pos+1] == '\n':
new_content = existing_content[:insert_pos] + '\n' + changelog_content + existing_content[insert_pos:]
else:
new_content = existing_content[:insert_pos] + '\n' + changelog_content + existing_content[insert_pos+1:]
else:
# 没有找到 CHANGELOG 标题,在文件开头插入标题和内容
if existing_content.strip():
# 文件有内容但没有 CHANGELOG 标题
new_content = f"# :memo: CHANGELOG\n\n{changelog_content}{existing_content}"
else:
# 文件为空
new_content = f"# :memo: CHANGELOG\n\n{changelog_content}"
# 检查内容是否真的改变
content_changed = (new_content != existing_content)
version_exists = f"## :bookmark: {changelog_version}" in existing_content
if content_changed:
with open(changelog_file, 'w', encoding='utf-8') as f:
f.write(new_content)
print(f"✅ CHANGELOG updated successfully")
print(f" Added {len(commits)} commits to version {changelog_version}")
with open('/tmp/changelog_updated.txt', 'w') as f:
f.write('true')
with open('/tmp/content_changed.txt', 'w') as f:
@@ -605,7 +633,7 @@ jobs:
print(f" Version {changelog_version} already contains all {len(commits)} commits")
print(f" This usually happens when recreating a deleted tag")
print(f" Will still create Release from existing CHANGELOG content")
with open('/tmp/changelog_updated.txt', 'w') as f:
f.write('true') # 返回 true 以触发 Release 创建
with open('/tmp/content_changed.txt', 'w') as f:
@@ -613,7 +641,7 @@ jobs:
else:
# 既没有新内容,版本也不存在(不应该发生)
print(f"⚠️ Unexpected state: no content change and version doesn't exist")
with open('/tmp/changelog_updated.txt', 'w') as f:
f.write('false')
with open('/tmp/content_changed.txt', 'w') as f:
@@ -622,7 +650,7 @@ jobs:
UPDATED=$(cat /tmp/changelog_updated.txt)
CONTENT_CHANGED=$(cat /tmp/content_changed.txt 2>/dev/null || echo "false")
echo "changelog_updated=$UPDATED" >> $GITHUB_OUTPUT
echo "content_changed=$CONTENT_CHANGED" >> $GITHUB_OUTPUT
@@ -660,10 +688,10 @@ jobs:
else
echo "📝 提交 CHANGELOG 更新..."
git commit -m "${{ env.COMMIT_MSG }}"
echo "📤 推送到远程 ${{ env.MAIN_BRANCH }} 分支..."
git push https://oauth2:${{ env.ACCESS_TOKEN }}@${GITHUB_SERVER_URL#https://}/${{ github.repository }}.git ${{ env.MAIN_BRANCH }}
if [ $? -eq 0 ]; then
echo "✅ 推送成功"
else
@@ -944,7 +972,7 @@ jobs:
- ️ CHANGELOG.md 无需更新(内容已存在)
- ✅ Release 已创建
- ✅ CHANGELOG.md 已作为附件上传
💡 **说明**: 检测到这是重建已删除的 tag,CHANGELOG 中已包含所有提交内容,因此直接从现有内容创建 Release。
EOFREBUILD
fi
@@ -963,7 +991,7 @@ jobs:
可能的原因:
- 在标签之间未找到有效的提交记录
- 或者版本 \`${{ env.CHANGELOG_VERSION }}\` 已包含所有相关提交(常见于重新创建已删除的 tag)
💡 如果你删除了 tag 后重新创建,CHANGELOG 中的内容已经存在,无需重复添加。
EOFNOCOMMIT
fi
@@ -1017,7 +1045,7 @@ jobs:
echo " - Release 标题: ${{ env.RELEASE_TITLE_PROCESSED }}"
echo " - Pre-release: ${{ env.RELEASE_IS_PRERELEASE }}"
echo ""
if [ "${{ steps.changelog.outputs.content_changed }}" = "true" ]; then
echo "✅ 已完成的操作:"
echo " - CHANGELOG.md 已更新并推送到 ${{ env.MAIN_BRANCH }} 分支"
@@ -1054,4 +1082,4 @@ jobs:
run: |
echo "🧹 清理临时文件..."
rm -rf /tmp/commits.txt /tmp/changelog_updated.txt /tmp/content_changed.txt /tmp/release-body.txt /tmp/payload.json /tmp/release_response.json /tmp/upload_response_*.json
echo "✅ 清理完成"
echo "✅ 清理完成"