feat(ci): 添加自动版本递增和标签创建功能

- 新增 GitHub Actions 工作流文件 auto-tag.yml
- 实现基于提交信息的关键字跳过机制 ([skip release] / [no tag])
- 自动解析最新语义化版本号并递增修订号
- 使用 PAT 推送新标签到远程仓库
- 输出版本变更相关信息供后续步骤使用
This commit is contained in:
GwWuYou 2025-12-09 16:59:09 +08:00
parent 5aa11ddc41
commit 404cb769e4
5 changed files with 264 additions and 4 deletions

112
.github/workflows/auto-tag.yml vendored Normal file
View File

@ -0,0 +1,112 @@
name: Auto Increment Version and Tag
# 工作流触发条件配置
# 当向 main 或 master 分支推送代码时触发
# 或者当针对 main 或 master 的 PR 被合并关闭时触发
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
types: [ closed ]
jobs:
auto-tag:
name: Auto Increment Version and Create Tag
runs-on: ubuntu-latest
# 条件判断:仅在推送事件或已合并的 PR 关闭事件中执行
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true)
permissions:
contents: write
steps:
# 步骤一:检出仓库代码
# 使用 actions/checkout 动作获取完整的 Git 历史用于查找已有标签
- name: Checkout code
uses: actions/checkout@v4
with:
lfs: true
fetch-depth: 0 # 获取全部历史记录以查找现有标签
persist-credentials: false
# 步骤二:检查是否需要跳过打标签操作
# 根据最新提交信息决定是否继续后续流程
- name: Check for skip keyword
id: check_skip
run: |
# 检查最近一次提交信息是否包含跳过关键词
LAST_COMMIT_MSG=$(git log -1 --pretty=format:"%B")
if [[ "$LAST_COMMIT_MSG" == *"[skip release]"* ]] || [[ "$LAST_COMMIT_MSG" == *"[no tag]"* ]]; then
echo "skip_tag=true" >> $GITHUB_OUTPUT
echo "Skipping tag creation due to skip keyword in commit message"
else
echo "skip_tag=false" >> $GITHUB_OUTPUT
echo "No skip keyword found, proceeding with tag creation"
fi
echo "Last commit message: $LAST_COMMIT_MSG"
# 步骤三:计算下一个版本号(若未被跳过)
# 自动解析当前最新标签并递增修订号生成新的语义化版本号
- name: Get next version
id: get_next_version
if: steps.check_skip.outputs.skip_tag == 'false'
run: |
# 获取最新的标签版本号,如果没有标签则默认为 0.0.0
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
# 移除可能存在的 v 前缀
VERSION_NUM=${LATEST_TAG#v}
# 解析主版本号、次版本号和修订号
MAJOR=$(echo $VERSION_NUM | cut -d. -f1)
MINOR=$(echo $VERSION_NUM | cut -d. -f2)
PATCH=$(echo $VERSION_NUM | cut -d. -f3)
# 递增修订号
PATCH=$((PATCH + 1))
# 构造新版本号
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
NEW_TAG="v$NEW_VERSION"
echo "latest_tag=$LATEST_TAG"
echo "new_version=$NEW_VERSION"
echo "new_tag=$NEW_TAG"
echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "new_tag=$NEW_TAG" >> $GITHUB_OUTPUT
# 步骤四:创建并推送新标签到远程仓库(若未被跳过)
# 使用个人访问令牌(PAT)进行身份验证完成推送操作
- name: Create tag and push (using PAT)
if: steps.check_skip.outputs.skip_tag == 'false'
env:
PAT: ${{ secrets.PAT_TOKEN }}
REPO: ${{ github.repository }}
NEW_TAG: ${{ steps.get_next_version.outputs.new_tag }}
run: |
set -e
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
echo "Creating annotated tag $NEW_TAG"
git tag -a "$NEW_TAG" -m "Auto-generated tag: $NEW_TAG"
# 推送单个 tag使用 PAT 作为 HTTPS token
echo "Pushing tag $NEW_TAG to origin using PAT"
git push "https://x-access-token:${PAT}@github.com/${REPO}.git" "refs/tags/${NEW_TAG}"
# 步骤五:输出本次成功创建的新版本相关信息(若未被跳过)
- name: Print version info
if: steps.check_skip.outputs.skip_tag == 'false'
run: |
echo "Previous tag was: ${{ steps.get_next_version.outputs.latest_tag }}"
echo "New tag created: ${{ steps.get_next_version.outputs.new_tag }}"
echo "Version number: ${{ steps.get_next_version.outputs.new_version }}"
# 步骤六:输出跳过原因信息(如果检测到了跳过关键字)
- name: Print skip info
if: steps.check_skip.outputs.skip_tag == 'true'
run: |
echo "Tag creation skipped due to commit message containing skip keyword"

59
.github/workflows/publish.yml vendored Normal file
View File

@ -0,0 +1,59 @@
name: Publish NuGet (on push to main)
# 触发条件:当有标签被推送到仓库时触发该工作流。
# 支持任意格式的标签名,例如 `1.0.0` 或 `v1.0.0`。
on:
push:
tags:
- '*' # 匹配所有标签推送事件
# 权限设置:授予写入 contents 的权限,
# 这样 GITHUB_TOKEN 才能调用 GitHub Releases API 创建发布。
permissions:
contents: write
packages: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore -c Release
- name: Test
run: dotnet test --no-build -c Release --verbosity normal
- name: Pack
run: dotnet pack --no-build -c Release -o ./packages
- name: Show packages
run: ls -la ./packages || true
- name: Publish to NuGet
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: |
set -e
if [ -z "$(ls -A ./packages 2>/dev/null)" ]; then
echo "No packages found in ./packages"
exit 1
fi
echo "Publishing packages to nuget.org..."
dotnet nuget push "./packages/*.nupkg" \
--api-key $NUGET_API_KEY \
--source https://api.nuget.org/v3/index.json \
--skip-duplicate

72
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,72 @@
name: Create Release (on tag)
on:
push:
tags:
- '*'
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout repository (at tag)
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: true
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore -c Release
- name: Pack
run: dotnet pack --no-build -c Release -o ./packages
- name: Get Version from .nupkg
id: get_version
run: |
set -e
PACKAGE_FILE=$(find ./packages -name "*.nupkg" | head -n 1)
if [ -z "$PACKAGE_FILE" ]; then
echo "No .nupkg file found in ./packages"
exit 1
fi
VERSION=$(unzip -p "$PACKAGE_FILE" *.nuspec 2>/dev/null | sed -n 's:.*<version>\(.*\)</version>.*:\1:p' | head -n1)
if [ -z "$VERSION" ]; then
echo "Failed to parse version from $PACKAGE_FILE"
exit 1
fi
echo "package_file=$PACKAGE_FILE" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Create GitHub Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref_name }}
release_name: "Release ${{ github.ref_name }}"
body: "Release created by CI for tag ${{ github.ref_name }} (package version ${{ steps.get_version.outputs.version }})"
draft: false
prerelease: false
- name: Upload .nupkg to Release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ steps.get_version.outputs.package_file }}
asset_name: ${{ steps.get_version.outputs.package_file && (steps.get_version.outputs.package_file | basename) || 'package.nupkg' }}
asset_content_type: application/octet-stream

View File

@ -1,9 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>GFramework</PackageId>
<Authors>GeWuYou</Authors>
<Product>GFramework</Product>
<Description>A game development framework inspired by QFramework</Description>
<Copyright>Copyright © 2025</Copyright>
<RepositoryUrl>https://github.com/GeWuYou/GFramework</RepositoryUrl>
<PackageProjectUrl>https://github.com/GeWuYou/GFramework</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageTags>game;framework;godot</PackageTags>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<RepositoryType>git</RepositoryType>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
</Project>
</Project>

View File

@ -1,4 +1,6 @@
# 项目介绍
# 项目介绍
本项目参考(CV)自[QFramework](https://github.com/liangxiegame/QFramework)
# 为什么要有这个项目
- 原来的项目是单文件框架,我把框架拆成多个文件,方便管理
- 原来的项目是单文件框架,我把框架拆成多个文件,方便管理
- 纯粹个人自用,要使用还是请访问[QFramework](https://github.com/liangxiegame/QFramework)