如何让semantic-release仅在GitLab CI流水线完成后触发版本发布?
解决方案:拆分Semantic-Release流程,延迟标签创建至全流程成功后
完全可以通过拆分semantic-release的执行步骤,将版本分析、CHANGELOG生成放在早期的Versioning阶段,而把标签创建、GitLab发布移到所有流水线阶段成功后的独立阶段,彻底解决流水线失败重跑时的标签冲突问题。
1. 修改Versioning阶段配置
调整Versioning阶段的脚本,仅执行版本计算、CHANGELOG生成与提交操作,不触发标签创建和发布。我们通过临时禁用@semantic-release/gitlab插件实现这一点:
version: tags: - macOS stage: version script: - export PATH=$PATH:/usr/local/bin # 配置semantic-release的npm仓库 - npm ci --cache .npm --prefer-offline - | { echo "@${CI_PROJECT_ROOT_NAMESPACE}:registry=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/" echo "${CI_API_V4_URL#https?}/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=\${CI_JOB_TOKEN}" } | tee -a .npmrc # 创建临时配置文件,移除GitLab发布插件 - cat > .releaserc-temp.json << EOF { "branches": ["main", "develop"], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", [ "@semantic-release/changelog", { "changelogFile": "public/CHANGELOG.md" } ], [ "@semantic-release/git", { "assets": ["public/CHANGELOG.md"] } ] ] } EOF # 运行简化版semantic-release,仅生成并提交CHANGELOG - npx semantic-release --extends .releaserc-temp.json --no-ci # 提取版本号并保存为流水线产物 - VERSION=$(grep -i -ow '\d\.\d\.\d' public/CHANGELOG.md | head -1) - echo $VERSION > public/VERSION.txt - echo $VERSION artifacts: name: "Changelog" paths: - public/*
2. 添加Finalize Release阶段
在流水线末尾新增一个阶段,仅当前面所有阶段(Build/Test/Deploy)全部成功后才执行,这里运行完整的semantic-release来创建标签和完成GitLab发布:
# 在.gitlab-ci.yml的末尾添加此阶段 finalize_release: tags: - macOS stage: finalize_release needs: ["deploy"] # 依赖Deploy阶段,确保全流程执行成功 script: - export PATH=$PATH:/usr/local/bin # 重新配置semantic-release环境 - npm ci --cache .npm --prefer-offline - | { echo "@${CI_PROJECT_ROOT_NAMESPACE}:registry=${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/" echo "${CI_API_V4_URL#https?}/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=\${CI_JOB_TOKEN}" } | tee -a .npmrc # 运行完整semantic-release,创建标签并发布到GitLab - npm run semantic-release only: - main - develop
3. 保留原.releaserc.json配置
原有的.releaserc.json无需修改,Finalize阶段会使用它的完整配置,包括@semantic-release/gitlab插件来完成标签创建和发布流程。
核心逻辑说明
- Versioning阶段:仅负责版本计算、CHANGELOG生成与提交,不创建任何标签。即使流水线后续失败重跑,此阶段只会重复生成相同的CHANGELOG(无新变更时不会重复推送),不会触发标签冲突。
- Finalize阶段:只有当Build/Test/Deploy全流程成功后才执行,此时semantic-release会基于已提交的CHANGELOG和提交历史确认版本号,创建对应标签并完成GitLab发布,从根源避免了提前创建标签导致的重跑冲突。
- 版本一致性:两次semantic-release执行基于相同的提交历史,计算出的版本号完全一致,不会出现版本不匹配的问题。
内容的提问来源于stack exchange,提问作者Roland Schützenhofer
相关产品推荐
相关产品推荐

