如何在GitLab CI脚本中将新版本号保存至package.json?
解决GitLab CI中版本号无法保存回package.json的问题
问题根源
- 版本递增逻辑错误:用
bc计算版本号会把三段式版本号当成小数处理(比如1.0.9会被识别为1.09),导致递增结果不符合语义化版本规则。 - CI环境特性限制:GitLab Runner默认在临时工作目录执行任务,修改后的
package.json如果不提交并推送到仓库,后续构建会重新拉取原始代码,无法读取到修改。 - Git权限不足:默认
CI_JOB_TOKEN没有推送代码的权限,无法将版本变更同步到仓库。
修正后的脚本实现
方案1:使用npm内置版本递增命令(推荐)
npm自带的version命令可直接处理语义化版本递增,自动生成提交记录,无需手动拆分计算:
build_android: stage: build before_script: # 配置Git用户信息(CI环境默认无此配置,会导致提交失败) - git config --global user.name "GitLab CI/CD" - git config --global user.email "ci@example.com" # 拉取最新代码,避免版本变更冲突 - git fetch origin $CI_COMMIT_BRANCH - git checkout $CI_COMMIT_BRANCH - git pull origin $CI_COMMIT_BRANCH script: # 递增补丁版本号(patch对应第三位,minor是第二位,major是第一位) - npm version patch --no-git-tag-version # 不需要自动打tag可加此参数 # 验证更新后的版本号 - export NEW_VERSION=$(node -p "require('./package.json').version") - echo "Updated version number: $NEW_VERSION" # 提交版本变更 - git add package.json package-lock.json # 若存在package-lock.json需一并提交 - git commit -m "chore: bump version to $NEW_VERSION" # 推送到仓库(需确保CI_JOB_TOKEN有推送权限) - git push https://gitlab-ci-token:$CI_JOB_TOKEN@$CI_REPOSITORY_URL $CI_COMMIT_BRANCH only: - main # 按需指定触发分支
方案2:手动处理版本号字符串(自定义递增逻辑)
如果需要自定义版本递增规则,用Node脚本替代bc,避免小数计算错误:
build_android: stage: build before_script: - git config --global user.name "GitLab CI/CD" - git config --global user.email "ci@example.com" - git fetch origin $CI_COMMIT_BRANCH - git checkout $CI_COMMIT_BRANCH - git pull origin $CI_COMMIT_BRANCH script: # 用Node脚本拆分并递增版本号 - export NEW_VERSION=$(node -e " const pkg = require('./package.json'); const parts = pkg.version.split('.'); parts[2] = parseInt(parts[2]) + 1; // 递增第三位,可按需修改为其他位 console.log(parts.join('.')); ") - echo "New version number: $NEW_VERSION" # 更新package.json - npm version $NEW_VERSION --no-git-tag-version # 提交并推送变更 - git add package.json package-lock.json - git commit -m "chore: bump version to $NEW_VERSION" - git push https://gitlab-ci-token:$CI_JOB_TOKEN@$CI_REPOSITORY_URL $CI_COMMIT_BRANCH
关键配置说明
- Git权限配置:
- 进入项目
Settings > CI/CD > Token Access,勾选Allow CI job tokens to push to the project,开放推送权限。 - 若使用私有仓库,也可以用个人访问令牌(PAT)替代
CI_JOB_TOKEN,格式为https://<用户名>:<PAT>@$CI_REPOSITORY_URL。
- 进入项目
- 冲突避免:执行版本变更前拉取最新代码,防止本地修改与远程仓库冲突。
- package-lock.json处理:使用npm时,版本号变更会同步更新
package-lock.json,需一并提交。
内容的提问来源于stack exchange,提问作者CodeMan03
相关产品推荐
相关产品推荐

