如何在GitLab pipeline中分步实现semantic versioning
GitLab Pipeline 落地 Semantic Versioning 实操流程
前置准备
- 项目级访问令牌配置:进入项目「设置 > 访问令牌」,创建勾选
api、write_repository权限的令牌,过期时间按团队安全规则设置,将令牌值存入项目CI/CD变量,变量名设为GITLAB_TOKEN,勾选「保护变量」选项,仅允许受保护分支/标签的pipeline读取该变量,避免权限泄露。 - 统一提交规范:所有合入主干的提交必须遵循Conventional Commits约定,规则对应关系固定:
- 提交信息带
feat:前缀 → 次版本(minor)+1 - 提交信息带
fix:前缀 → 修订版本(patch)+1 - 提交信息正文/脚注带
BREAKING CHANGE:标识 → 主版本(major)+1
这个规则是后续自动计算版本号的核心依据,不需要人工介入判断版本升降级。
- 提交信息带
- 初始化基准标签:老项目在当前主干最新提交上手动打第一个基准标签,比如
v1.0.0,后续所有版本都基于该标签的提交记录自动递增;新项目直接打v0.0.1作为初始标签即可。
分步落地流程
- 新增提交信息校验环节
在pipeline的测试阶段加commitlint校验,所有MR在合并前自动扫描提交信息,不符合规范直接阻断合并,从入口避免无效提交影响版本计算,job配置示例:stages: - lint - test - build - release commitlint_check: stage: lint image: node:20-alpine rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" script: - npm i -g @commitlint/cli @commitlint/config-conventional - commitlint --from=$CI_MERGE_REQUEST_DIFF_BASE_SHA --to=$CI_COMMIT_SHA --extends @commitlint/config-conventional - 配置版本自动发布job
用semantic-release作为版本计算工具,不需要自己写脚本解析提交、算版本、打标签,所有逻辑都有成熟插件实现。release阶段放在构建、测试全量通过之后执行,仅在默认主干分支触发,避免在功能分支打出正式版本标签,job配置示例:semantic_publish: stage: release image: node:20-alpine rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH before_script: - npm i -g semantic-release @semantic-release/gitlab @semantic-release/changelog @semantic-release/git script: # 首次上线先把下面命令换成 semantic-release --dry-run 验证版本计算逻辑是否符合预期,确认无误再改回正式命令 - semantic-release variables: GITLAB_URL: $CI_SERVER_URL NPM_TOKEN: "false" # 非npm项目直接填false跳过npm发布逻辑,npm包项目替换为对应的npm仓库token - 新增版本规则配置文件
在仓库根目录创建.releaserc.json,定义版本发布的具体规则,配置示例:{ "branches": ["main"], // 替换为你团队的默认主干分支名,比如master "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", // 自动生成CHANGELOG.md更新日志 "@semantic-release/gitlab", // 自动在GitLab创建Release条目 [ "@semantic-release/git", { "assets": ["CHANGELOG.md"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ] ] } - 配置分支保护规则
进入项目「设置 > 仓库 > 受保护分支」,将默认主干分支设为受保护状态,关闭开发者直接push权限,所有代码必须通过MR、经过提交校验、CI测试通过后才能合入,避免随意提交打乱版本序列。
生产环境注意事项
- 自动生成的版本号会直接作为Git标签存在,后续构建镜像、制品包的时候直接引用
$CI_COMMIT_TAG变量即可,不需要手动传版本参数,比如镜像tag可以直接写为your-registry.com/app:$CI_COMMIT_TAG。 - 功能分支如果需要生成测试版本,不要和正式版本规则混用,可以单独配置预发布版本规则,版本号带分支名后缀比如
v1.3.0-feat-user-center.1,和正式版本做区分。 - 多模块单体仓库不要全仓共用一个版本号,按模块路径配置semantic-release的扫描范围,每个模块单独计算版本、打标签,避免无关模块的改动触发无意义的版本递增。
避坑提示:自动生成release提交时必须在commit信息里带
[skip ci]标识,否则会触发pipeline循环执行,上面的配置已经默认加了该标识,不要随意删除。
内容的提问来源于stack exchange,提问作者Learning
相关产品推荐
相关产品推荐

