forgeboot/.gitlab/workflows/.gitlab-ci.main.yml
gewuyou 40f58efd82 ci:优化 GitLab CI/CD 工作流配置
- 重构配置文件结构,提高可读性和可维护性
- 添加复用片段(anchors)简化重复配置
- 优化 tag、publish、reset 和 mirror job 的执行流程
- 修复部分 job 的执行顺序和依赖关系
- 更新镜像和命令执行方式,提高执行效率
2025-08-13 20:33:06 +08:00

180 lines
6.0 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

stages:
- tag
- publish
- reset
- mirror
variables:
GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle"
GIT_STRATEGY: fetch
GIT_DEPTH: "0"
before_script:
- rm -rf "$GRADLE_USER_HOME/.tmp" || true
# -------- 复用片段anchors ------------------------------------
# 统一镜像alpine/git + 清空 ENTRYPOINT避免 "git sh" 问题
.alpine_git_image: &alpine_git_image
image:
name: alpine/git:latest
entrypoint: [ "" ]
# 统一 Git 身份配置
.git_identity: &git_identity
- git config --global user.email "pipeline@${GITLAB_URL}"
- git config --global user.name "Project Pipeline Bot"
# 统一远端地址变量GitLab & GitHub
.remotes: &remotes
- export GL_REPO_URL="https://oauth2:${PIPELINE_BOT_TOKEN}@${GITLAB_URL}/${CI_PROJECT_PATH}.git"
- export GH_REPO_URL="https://x-access-token:${GITHUB_PUSH_TOKEN}@github.com/GeWuYou/forgeboot.git"
# tag 任务常用准备:清理本地 tag、拉取远端 tag 和 main
.tag_prepare: &tag_prepare
- echo "🧹 删除所有本地 tag..."
- git tag -l | xargs -r git tag -d || true
- echo "🔍 拉取远程 tag 和 main"
- git fetch --tags --force --prune
- git fetch origin main --force
- MAIN_COMMIT=$(git rev-parse origin/main)
- echo "🔗 当前 main commit -> $MAIN_COMMIT"
# 🏷️ 自动打标签
# tag job: 在main分支提交时自动创建并推送新的语义化版本标签
# 参数:
# stage: 指定该job属于tag阶段
# image: 指定使用alpine/git镜像并清空entrypoint避免git sh问题
# rules: 定义触发规则仅当提交到main分支且提交信息不包含"ci"(忽略大小写)时触发
# script: 执行标签创建和推送的具体脚本
# tags: 指定运行该job的runner标签为java
tag:
stage: tag
<<: *alpine_git_image
rules:
- if: '$CI_COMMIT_BRANCH == "main" && $CI_COMMIT_MESSAGE !~ /ci/i'
tags: [ java ]
before_script:
- *git_identity
- *remotes
- *tag_prepare
script:
- echo "📦 获取最新 tag..."
# 使用 git 自带排序(无需 coreutils 的 sort -V
- LATEST_TAG=$(git tag --list '*' --sort=-v:refname | head -n1 || true)
- if [ -z "$LATEST_TAG" ]; then LATEST_TAG="0.0.0"; fi
- echo "🔖 最新 tag -> $LATEST_TAG"
# 解析 semver不带 v 前缀)
- VERSION=${LATEST_TAG#v}
- MAJOR=$(echo "$VERSION" | cut -d. -f1)
- MINOR=$(echo "$VERSION" | cut -d. -f2)
- PATCH=$(echo "$VERSION" | cut -d. -f3)
# 规则patch +1满 10 进位到 minor
- PATCH=$((PATCH + 1))
- if [ "$PATCH" -ge 10 ]; then PATCH=0; MINOR=$((MINOR+1)); echo "🔁 patch 达 10 进位MINOR=$MINOR, PATCH=$PATCH"; fi
- NEW_TAG="${MAJOR}.${MINOR}.${PATCH}"
- echo "🏷️ 新 tag -> $NEW_TAG"
# 同一 commit 不重复打 tag
- if git tag --points-at "$MAIN_COMMIT" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' >/dev/null; then
echo "⏭️ 当前 commit 已有 semver tag跳过";
exit 0;
fi
- git tag "$NEW_TAG" "$MAIN_COMMIT"
- git push "$GL_REPO_URL" "$NEW_TAG"
- echo "✅ tag $NEW_TAG 已推送到 GitLab"
- git remote add github "$GH_REPO_URL" || git remote set-url github "$GH_REPO_URL"
- git push github "$NEW_TAG"
- echo "✅ tag $NEW_TAG 已同步至 GitHub"
# 📦 发布至 GitLab 与 GitHub Maven 仓库
# publish job: 将构建产物发布到GitLab和GitHub的Maven仓库
# 参数:
# stage: 指定该job属于publish阶段
# needs: 指定依赖tag job完成后再执行
# rules: 定义触发规则仅当提交到main分支且提交信息不包含"ci"(忽略大小写)时触发
# cache: 定义缓存策略缓存Gradle相关目录以加速构建
# script: 执行发布到Maven仓库的具体脚本
# tags: 指定运行该job的runner标签为java
publish:
stage: publish
needs: [ "tag" ]
rules:
- if: '$CI_COMMIT_BRANCH == "main" && $CI_COMMIT_MESSAGE !~ /ci/i'
cache:
key:
files:
- gradle/libs.versions.toml
- "**/*.gradle.kts"
prefix: lab-agent
paths:
- .gradle/caches/
- .gradle/wrapper/
- .gradle/kotlin-profile/
- .kotlin/
policy: pull-push
tags: [ java ]
script:
- echo "🔧 授予 gradlew 执行权限..."
- chmod +x gradlew
- ./gradlew publishMavenJavaPublicationToGitLabRepository
- ./gradlew publishMavenJavaPublicationToGitHubRepository --continue
# 🔄 重建 test 分支
# reset job: 基于main分支重建test分支
# 参数:
# stage: 指定该job属于reset阶段
# image: 指定使用alpine/git镜像并清空entrypoint避免git sh问题
# rules: 定义触发规则仅当提交到main分支时触发
# script: 执行重建test分支的具体脚本
# tags: 指定运行该job的runner标签为java
reset:
stage: reset
<<: *alpine_git_image
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
tags: [ java ]
before_script:
- *git_identity
- *remotes
script:
- set -euo pipefail
- echo "🔄 重建 test 分支..."
- git clone --branch main "$GL_REPO_URL" repo
- cd repo
- git checkout -B test
- git push origin test --force
- echo "✅ test 分支已重建完成"
# 🔁 同步到 GitHub
# mirror-to-github job: 将GitLab的main分支同步到GitHub
# 参数:
# stage: 指定该job属于mirror阶段
# image: 指定使用alpine/git镜像并清空entrypoint避免git sh问题
# rules: 定义触发规则仅当提交到main分支时触发
# script: 执行同步到GitHub的具体脚本
# tags: 指定运行该job的runner标签为java
mirror-to-github:
stage: mirror
<<: *alpine_git_image
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
tags: [ java ]
before_script:
- *git_identity
- *remotes
script:
- set -euo pipefail
- echo "🔄 clone GitLab 仓库..."
- git clone --branch main "$GL_REPO_URL" repo
- cd repo
- echo "🔗 添加/更新 GitHub 远程..."
- git remote add github "$GH_REPO_URL" || git remote set-url github "$GH_REPO_URL"
- echo "🚀 推送 main 到 GitHub..."
- git push github main --force
- echo "✅ GitHub 同步完成"