Skip to content

feat: SEO优化及多语言sitemap生成 #6

feat: SEO优化及多语言sitemap生成

feat: SEO优化及多语言sitemap生成 #6

name: Release on Version Change
on:
push:
branches:
- frontend-remake
paths:
- 'package.json'
- 'public/config/version.json'
- '.github/workflows/release-on-version-change.yml'
workflow_dispatch: # 允许手动触发
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write # 需要权限来创建release和tag
id-token: write
# 版本检测在步骤中完成,避免重复release
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整历史记录用于生成changelog
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v4
with:
node-version: '20.x'
check-latest: true
- name: Verify installation
shell: bash
run: |
echo "Checking installations..."
node --version
npm --version
pnpm --version || echo "pnpm not required for release workflow"
echo "Installations verified."
- name: Check if version actually changed
id: check-version
shell: bash
run: |
# 检查触发事件类型
echo "Event name: $GITHUB_EVENT_NAME"
# 如果是手动触发,总是发布
if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
echo "Manual trigger detected. Will proceed with release."
echo "should_release=true" >> $GITHUB_OUTPUT
exit 0
fi
# 获取当前版本信息
CURRENT_PACKAGE_VERSION=$(jq -r .version package.json)
CURRENT_POLICY_VERSION=$(jq -r .policyVersion public/config/version.json)
CURRENT_APP_VERSION=$(jq -r .appVersion public/config/version.json)
# 获取上一个提交的版本信息(如果存在)
if git log -n 1 --oneline > /dev/null 2>&1; then
PREV_PACKAGE_VERSION=$(git show HEAD~1:package.json 2>/dev/null | jq -r .version 2>/dev/null || echo "none")
PREV_POLICY_VERSION=$(git show HEAD~1:public/config/version.json 2>/dev/null | jq -r .policyVersion 2>/dev/null || echo "none")
PREV_APP_VERSION=$(git show HEAD~1:public/config/version.json 2>/dev/null | jq -r .appVersion 2>/dev/null || echo "none")
else
PREV_PACKAGE_VERSION="none"
PREV_POLICY_VERSION="none"
PREV_APP_VERSION="none"
fi
echo "Previous versions:"
echo " Package: $PREV_PACKAGE_VERSION"
echo " Policy: $PREV_POLICY_VERSION"
echo " App: $PREV_APP_VERSION"
echo "Current versions:"
echo " Package: $CURRENT_PACKAGE_VERSION"
echo " Policy: $CURRENT_POLICY_VERSION"
echo " App: $CURRENT_APP_VERSION"
# 检查是否有版本变化
VERSION_CHANGED=false
if [[ "$CURRENT_PACKAGE_VERSION" != "$PREV_PACKAGE_VERSION" ]]; then
echo "Package version changed from $PREV_PACKAGE_VERSION to $CURRENT_PACKAGE_VERSION"
VERSION_CHANGED=true
fi
if [[ "$CURRENT_POLICY_VERSION" != "$PREV_POLICY_VERSION" ]]; then
echo "Policy version changed from $PREV_POLICY_VERSION to $CURRENT_POLICY_VERSION"
VERSION_CHANGED=true
fi
if [[ "$CURRENT_APP_VERSION" != "$PREV_APP_VERSION" ]]; then
echo "App version changed from $PREV_APP_VERSION to $CURRENT_APP_VERSION"
VERSION_CHANGED=true
fi
if [[ "$VERSION_CHANGED" == "true" ]]; then
echo "Version change detected, will proceed with release."
echo "should_release=true" >> $GITHUB_OUTPUT
else
echo "No version change detected. Skipping release."
echo "should_release=false" >> $GITHUB_OUTPUT
fi
- name: Determine release version
id: determine-version
if: steps.check-version.outputs.should_release == 'true'
shell: bash
run: |
# 优先使用package.json的version作为release版本
RELEASE_VERSION=$(jq -r .version package.json)
echo "Using package.json version: $RELEASE_VERSION"
# 验证版本格式(应该符合语义化版本)
if [[ ! "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "Warning: Version format may not be standard semantic versioning"
fi
echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT
echo "tag_name=v$RELEASE_VERSION" >> $GITHUB_OUTPUT
# 获取版本描述
POLICY_VERSION=$(jq -r .policyVersion public/config/version.json)
APP_VERSION=$(jq -r .appVersion public/config/version.json)
echo "policy_version=$POLICY_VERSION" >> $GITHUB_OUTPUT
echo "app_version=$APP_VERSION" >> $GITHUB_OUTPUT
- name: Generate changelog
id: changelog
if: steps.check-version.outputs.should_release == 'true'
shell: bash
run: |
# 获取当前tag名
TAG_NAME="${{ steps.determine-version.outputs.tag_name }}"
# 查找上一个tag
PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [[ -z "$PREV_TAG" ]]; then
echo "No previous tag found. Generating changelog from first commit."
# 获取所有提交信息
COMMITS=$(git log --oneline --pretty=format:"- %s" --reverse)
CHANGELOG_HEADER="## 初始版本 v${{ steps.determine-version.outputs.release_version }}\n\n首次发布。包含以下提交:\n\n"
else
echo "Previous tag found: $PREV_TAG"
# 获取从上个tag到现在的提交信息
COMMITS=$(git log --oneline --pretty=format:"- %s" "${PREV_TAG}..HEAD")
CHANGELOG_HEADER="## v${{ steps.determine-version.outputs.release_version }} ($(date '+%Y-%m-%d'))\n\n自 ${PREV_TAG} 以来的变更:\n\n"
fi
# 如果COMMITS为空(可能没有新提交)
if [[ -z "$COMMITS" ]]; then
COMMITS="- 无具体提交信息(版本号变更)"
fi
# 构建完整的发布说明
RELEASE_BODY="${CHANGELOG_HEADER}${COMMITS}\n\n### 版本信息\n- 应用版本: ${{ steps.determine-version.outputs.release_version }}\n- 用户协议版本: ${{ steps.determine-version.outputs.policy_version }}\n- 内部版本: ${{ steps.determine-version.outputs.app_version }}\n\n*自动生成于 $(date '+%Y-%m-%d %H:%M:%S')*"
# 输出到GITHUB_OUTPUT(需要处理多行文本)
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "release_body<<$EOF" >> $GITHUB_OUTPUT
echo "$RELEASE_BODY" >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
echo "Generated changelog with $(echo "$COMMITS" | wc -l) commits"
- name: Create GitHub Release
id: create-release
if: steps.check-version.outputs.should_release == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.determine-version.outputs.tag_name }}
name: v${{ steps.determine-version.outputs.release_version }}
body: ${{ steps.changelog.outputs.release_body }}
draft: false
prerelease: false
generate_release_notes: false # 不使用GitHub自动生成,使用我们自己的changelog
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Output release info
if: steps.check-version.outputs.should_release == 'true'
shell: bash
run: |
echo "Release created successfully!"
echo "Version: v${{ steps.determine-version.outputs.release_version }}"
echo "Tag: ${{ steps.determine-version.outputs.tag_name }}"
echo "Release URL: ${{ steps.create-release.outputs.html_url }}"