ci:优化 GitLab CI/CD 工作流配置

- 重构配置文件结构,提高可读性和可维护性
- 添加复用片段(anchors)简化重复配置
- 优化 tag、publish、reset 和 mirror job 的执行流程
- 修复部分 job 的执行顺序和依赖关系
- 更新镜像和命令执行方式,提高执行效率
This commit is contained in:
gewuyou 2025-08-13 20:33:06 +08:00
parent be03204a73
commit 40f58efd82

View File

@ -6,21 +6,32 @@ stages:
variables: variables:
GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle" GRADLE_USER_HOME: "$CI_PROJECT_DIR/.gradle"
GIT_STRATEGY: fetch
GIT_DEPTH: "0"
before_script: before_script:
- rm -rf $GRADLE_USER_HOME/.tmp || true - rm -rf "$GRADLE_USER_HOME/.tmp" || true
# 🏷️ 自动打标签 # -------- 复用片段anchors ------------------------------------
tag:
stage: tag # 统一镜像alpine/git + 清空 ENTRYPOINT避免 "git sh" 问题
.alpine_git_image: &alpine_git_image
image: image:
name: alpine/git:latest name: alpine/git:latest
entrypoint: [ "" ] entrypoint: [ "" ]
rules:
- if: '$CI_COMMIT_BRANCH == "main" && $CI_COMMIT_MESSAGE !~ /ci/i' # 统一 Git 身份配置
script: .git_identity: &git_identity
- git config --global user.email "pipeline@${GITLAB_URL}" - git config --global user.email "pipeline@${GITLAB_URL}"
- git config --global user.name "Project Pipeline Bot" - 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..." - echo "🧹 删除所有本地 tag..."
- git tag -l | xargs -r git tag -d || true - git tag -l | xargs -r git tag -d || true
- echo "🔍 拉取远程 tag 和 main" - echo "🔍 拉取远程 tag 和 main"
@ -28,41 +39,67 @@ tag:
- git fetch origin main --force - git fetch origin main --force
- MAIN_COMMIT=$(git rev-parse origin/main) - MAIN_COMMIT=$(git rev-parse origin/main)
- echo "🔗 当前 main commit -> $MAIN_COMMIT" - echo "🔗 当前 main commit -> $MAIN_COMMIT"
- git fetch --tags
- git fetch origin main
- 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) - LATEST_TAG=$(git tag --list '*' --sort=-v:refname | head -n1 || true)
- if [ -z "$LATEST_TAG" ]; then LATEST_TAG="0.0.0"; fi - if [ -z "$LATEST_TAG" ]; then LATEST_TAG="0.0.0"; fi
- echo "🔖 最新 tag -> $LATEST_TAG" - echo "🔖 最新 tag -> $LATEST_TAG"
# 解析 semver不带 v 前缀)
- VERSION=${LATEST_TAG#v} - VERSION=${LATEST_TAG#v}
- MAJOR=$(echo "$VERSION" | cut -d. -f1) - MAJOR=$(echo "$VERSION" | cut -d. -f1)
- MINOR=$(echo "$VERSION" | cut -d. -f2) - MINOR=$(echo "$VERSION" | cut -d. -f2)
- PATCH=$(echo "$VERSION" | cut -d. -f3) - PATCH=$(echo "$VERSION" | cut -d. -f3)
# 规则patch +1满 10 进位到 minor
- PATCH=$((PATCH + 1)) - PATCH=$((PATCH + 1))
- if [ "$PATCH" -ge 10 ]; then PATCH=0; MINOR=$((MINOR+1)); echo "🔁 patch 达到 10进位MINOR=$MINOR, PATCH=$PATCH"; fi - if [ "$PATCH" -ge 10 ]; then PATCH=0; MINOR=$((MINOR+1)); echo "🔁 patch 达 10 进位MINOR=$MINOR, PATCH=$PATCH"; fi
- NEW_TAG="${MAJOR}.${MINOR}.${PATCH}" - NEW_TAG="${MAJOR}.${MINOR}.${PATCH}"
- echo "🏷️ 新 tag -> $NEW_TAG" - echo "🏷️ 新 tag -> $NEW_TAG"
- if git tag --points-at "$MAIN_COMMIT" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' > /dev/null; then # 同一 commit 不重复打 tag
echo "⏭️ 已存在 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; exit 0;
fi fi
- git tag $NEW_TAG $MAIN_COMMIT - git tag "$NEW_TAG" "$MAIN_COMMIT"
- git push https://oauth2:${PIPELINE_BOT_TOKEN}@${GITLAB_URL}/${CI_PROJECT_PATH}.git $NEW_TAG - git push "$GL_REPO_URL" "$NEW_TAG"
- echo "✅ tag $NEW_TAG 已推送" - echo "✅ tag $NEW_TAG 已推送到 GitLab"
# 添加 GitHub 远程并推送 tag
- git remote add github https://x-access-token:${GITHUB_PUSH_TOKEN}@github.com/GeWuYou/forgeboot.git - git remote add github "$GH_REPO_URL" || git remote set-url github "$GH_REPO_URL"
- git push github $NEW_TAG - git push github "$NEW_TAG"
- echo "✅ tag $NEW_TAG 已同步至 GitHub" - echo "✅ tag $NEW_TAG 已同步至 GitHub"
tags:
- java
# 📦 发布至 GitLab 与 GitHub Maven 仓库 # 📦 发布至 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: publish:
stage: publish stage: publish
needs: [ "tag" ] needs: [ "tag" ]
@ -80,53 +117,63 @@ publish:
- .gradle/kotlin-profile/ - .gradle/kotlin-profile/
- .kotlin/ - .kotlin/
policy: pull-push policy: pull-push
tags: [ java ]
script: script:
- echo "🔧 授予 gradlew 执行权限..." - echo "🔧 授予 gradlew 执行权限..."
- chmod +x gradlew - chmod +x gradlew
- ./gradlew publishMavenJavaPublicationToGitLabRepository - ./gradlew publishMavenJavaPublicationToGitLabRepository
- ./gradlew publishMavenJavaPublicationToGitHubRepository --continue - ./gradlew publishMavenJavaPublicationToGitHubRepository --continue
tags:
- java
# 🔄 重建 test 分支 # 🔄 重建 test 分支
# reset job: 基于main分支重建test分支
# 参数:
# stage: 指定该job属于reset阶段
# image: 指定使用alpine/git镜像并清空entrypoint避免git sh问题
# rules: 定义触发规则仅当提交到main分支时触发
# script: 执行重建test分支的具体脚本
# tags: 指定运行该job的runner标签为java
reset: reset:
stage: reset stage: reset
image: alpine:latest <<: *alpine_git_image
rules: rules:
- if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_BRANCH == "main"'
tags: [ java ]
before_script:
- *git_identity
- *remotes
script: script:
- set -euo pipefail - set -euo pipefail
- apk add --no-cache git - echo "🔄 重建 test 分支..."
- git config --global user.email "pipeline@${GITLAB_URL}" - git clone --branch main "$GL_REPO_URL" repo
- git config --global user.name "Project Pipeline Bot"
- git clone --branch main https://oauth2:${PIPELINE_BOT_TOKEN}@${GITLAB_URL}/${CI_PROJECT_PATH}.git repo
- cd repo - cd repo
- git checkout -B test - git checkout -B test
- git push origin test --force - git push origin test --force
- echo "✅ test 分支已重建完成" - echo "✅ test 分支已重建完成"
tags:
- java # 🔁 同步到 GitHub
# Mirror to 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: mirror-to-github:
stage: mirror stage: mirror
image: alpine:latest <<: *alpine_git_image
rules: rules:
- if: '$CI_COMMIT_BRANCH == "main"' - if: '$CI_COMMIT_BRANCH == "main"'
tags: [ java ]
before_script:
- *git_identity
- *remotes
script: script:
- set -euo pipefail - set -euo pipefail
- apk add --no-cache git openssh - echo "🔄 clone GitLab 仓库..."
- git config --global user.name "Project Pipeline Bot" - git clone --branch main "$GL_REPO_URL" repo
- git config --global user.email "pipeline@${GITLAB_URL}"
- echo "🔄 正在 clone 当前 GitLab 仓库..."
- git clone --branch main https://oauth2:${PIPELINE_BOT_TOKEN}@${GITLAB_URL}/${CI_PROJECT_PATH}.git repo
- cd repo - cd repo
- echo "🔗 添加/更新 GitHub 远程..."
- echo "🔗 添加 GitHub 远程地址..." - git remote add github "$GH_REPO_URL" || git remote set-url github "$GH_REPO_URL"
- git remote add github https://x-access-token:${GITHUB_PUSH_TOKEN}@github.com/GeWuYou/forgeboot.git - echo "🚀 推送 main 到 GitHub..."
- echo "🚀 推送 main 分支到 GitHub..."
- git push github main --force - git push github main --force
- echo "✅ GitHub 同步完成" - echo "✅ GitHub 同步完成"
tags:
- java