GitLab单Job内基于文件变更的多条件判断实现方案咨询
基于GitLab CI实现按模块文件变更自动递增package.json对应版本号
问题背景
需要根据server/client目录的文件变更,自动更新package.json中对应的serverVersion、clientVersion字段(可选同步更新全局version)。原设想的单Job多条件触发、变量标记变更的方式无法实现,以下是两种可行的落地方案:
方案1:拆分独立Job处理各模块变更
将server和client的版本更新拆分为两个独立Job,通过GitLab CI的rules:changes规则单独判断触发条件,逻辑清晰且支持并行执行。
示例.gitlab-ci.yml配置:
update-server-version: rules: - if: $CI_COMMIT_BRANCH == "main" # 根据实际需求调整分支条件 changes: - server/**/* # 监控server目录下所有文件变更 script: # 用jq工具读取并递增serverVersion(patch版本,最后一位+1) - CURRENT_VER=$(jq -r '.serverVersion' package.json) - NEW_VER=$(echo $CURRENT_VER | awk -F. -v OFS=. '{$NF++; print}') - jq --arg newVer "$NEW_VER" '.serverVersion = $newVer' package.json > tmp.json && mv tmp.json package.json # 自动提交版本变更到仓库 - git config --global user.name "GitLab CI/CD" - git config --global user.email "ci@example.com" - git add package.json - git commit -m "chore: increment server version to $NEW_VER" - git push origin $CI_COMMIT_BRANCH update-client-version: rules: - if: $CI_COMMIT_BRANCH == "main" changes: - client/**/* script: # 同理处理clientVersion - CURRENT_VER=$(jq -r '.clientVersion' package.json) - NEW_VER=$(echo $CURRENT_VER | awk -F. -v OFS=. '{$NF++; print}') - jq --arg newVer "$NEW_VER" '.clientVersion = $newVer' package.json > tmp.json && mv tmp.json package.json # 提交逻辑同上 - git config --global user.name "GitLab CI/CD" - git config --global user.email "ci@example.com" - git add package.json - git commit -m "chore: increment client version to $NEW_VER" - git push origin $CI_COMMIT_BRANCH
方案优势
- 每个Job独立触发,不会出现条件冲突或逻辑混乱
- 支持并行执行,提升CI效率
changes规则判断精准,仅在目标目录变更时触发
方案2:单Job内通过Git Diff判断变更模块
如果必须使用单个Job完成所有逻辑,可以通过git diff获取本次提交的变更文件列表,手动判断是否涉及server/client目录,再执行对应版本递增。
示例.gitlab-ci.yml配置:
update-versions: rules: - if: $CI_COMMIT_BRANCH == "main" changes: - server/**/* - client/**/* script: # 获取本次提交与上一次提交的变更文件列表(首次提交时用HEAD~1替代CI_COMMIT_BEFORE_SHA) - CHANGED_FILES=$(git diff --name-only ${CI_COMMIT_BEFORE_SHA:-HEAD~1} $CI_COMMIT_SHA) # 处理server版本递增 - if echo "$CHANGED_FILES" | grep -q "^server/"; then CURRENT_VER=$(jq -r '.serverVersion' package.json) NEW_VER=$(echo $CURRENT_VER | awk -F. -v OFS=. '{$NF++; print}') jq --arg newVer "$NEW_VER" '.serverVersion = $newVer' package.json > tmp.json && mv tmp.json package.json echo "Updated server version to $NEW_VER" fi # 处理client版本递增 - if echo "$CHANGED_FILES" | grep -q "^client/"; then CURRENT_VER=$(jq -r '.clientVersion' package.json) NEW_VER=$(echo $CURRENT_VER | awk -F. -v OFS=. '{$NF++; print}') jq --arg newVer "$NEW_VER" '.clientVersion = $newVer' package.json > tmp.json && mv tmp.json package.json echo "Updated client version to $NEW_VER" fi # 可选:同步更新全局version - if echo "$CHANGED_FILES" | grep -q -E "^server/|^client/"; then CURRENT_GLOBAL_VER=$(jq -r '.version' package.json) NEW_GLOBAL_VER=$(echo $CURRENT_GLOBAL_VER | awk -F. -v OFS=. '{$NF++; print}') jq --arg newVer "$NEW_GLOBAL_VER" '.version = $newVer' package.json > tmp.json && mv tmp.json package.json echo "Updated global version to $NEW_GLOBAL_VER" fi # 提交变更 - git config --global user.name "GitLab CI/CD" - git config --global user.email "ci@example.com" - git add package.json - git commit -m "chore: update versions based on module changes" - git push origin $CI_COMMIT_BRANCH
注意事项
- 确保GitLab Runner环境已安装
jq和awk(官方镜像通常自带,若缺失可在script中添加apt-get install -y jq awk安装) - 自动提交代码需要给CI Runner配置仓库权限(可通过Deploy Token或CI/CD变量存储Git凭证)
- 版本递增规则可按需调整:比如要递增minor版本(中间位+1,最后位归零),可修改awk命令为
{$2++; $3=0; print}
内容的提问来源于stack exchange,提问作者697
相关产品推荐
相关产品推荐

