能否分阶段执行SBT发布?CD流水线分步操作需求咨询
嘿,我来帮你搞定这个SBT项目的CD流水线方案,完全匹配你说的“先做预操作、等E2E过了再收尾”的需求。下面是一步步的具体实现思路,还有实用的示例:
整体流水线核心逻辑
这个流水线属于**“ gated 发布”**模式——前半段完成代码检出、预打标签、构建测试,中间用端到端测试做“关卡”,只有测试通过才执行最终的标签推送和制品上传,完美避免无效发布。
1. 初始阶段:Git检出与本地预打标签
- 先从Git仓库检出代码:不管你用Jenkins、GitLab CI还是其他流水线工具,自带的代码检出步骤就能搞定,或者手动执行
git clone <你的仓库地址>。 - 预打本地Git标签:这一步关键是只在本地生成标签,不推送到远程。可以用构建号或者提交哈希生成唯一标签,比如:
注意:绝对不要执行# 用流水线构建号生成标签(示例用GitLab CI的变量) TAG_NAME="v${CI_PIPELINE_ID}" git tag -a $TAG_NAME -m "Release Candidate: Pipeline ${CI_PIPELINE_ID}"git push origin $TAG_NAME,先把标签存在本地就行。
2. 构建与基础测试阶段:SBT操作
- 运行单元/集成测试:用SBT命令
sbt test,如果你的项目有单独的集成测试套件,可以用sbt it:test,确保基础测试全过才往下走。 - 打包应用:根据项目类型选择对应的SBT命令——普通JAR用
sbt package,需要胖包的话用sbt assembly,打包后的制品一般在target/scala-<你的Scala版本>/目录下。
3. 端到端测试阶段:部署与验证
- 部署二进制到测试环境:用你熟悉的方式上传,比如
scp传到测试服务器、或者用容器部署(Docker镜像推送到私有仓库再启动容器)。 - 运行端到端测试:执行你的E2E测试脚本(比如Cypress、Playwright或者自定义脚本),这是整个流水线的核心关卡——只有测试返回成功状态码,才会触发后续的收尾步骤。
4. 最终阶段:推送标签与上传制品到Artefactory
- 推送本地标签到远程Git仓库:E2E测试通过后,执行
git push origin $TAG_NAME,把预打的标签同步到远程,方便后续回溯或者基于标签发布。 - 上传制品到Artefactory:可以用Artefactory的CLI工具
jfrog,或者配置SBT直接上传。比如用CLI的示例命令:
提前把Artefactory的认证信息(比如API密钥)配置成流水线的环境变量,避免硬编码。# 假设你的胖包在target目录下,上传到Artefactory的指定仓库路径 jfrog rt upload target/scala-2.13/my-app-assembly-*.jar my-artefactory-repo/releases/$TAG_NAME/
额外的容错与优化建议
- 失败回滚:如果E2E测试失败,记得清理本地标签(
git tag -d $TAG_NAME),避免下次构建残留无效标签;同时清理测试环境的部署包,保持环境干净。 - 版本号唯一性:用流水线的唯一ID生成标签(比如GitLab的
CI_PIPELINE_ID、Jenkins的BUILD_ID),绝对不会出现标签重复冲突。 - SBT配置简化:可以在
build.sbt里提前配置Artefactory的仓库信息,后续上传更方便:
这样E2E通过后,直接执行publishTo := Some("Artefactory Releases" at "https://你的Artefactory地址/artifactory/libs-release-local") credentials += Credentials(Path.userHome / ".sbt" / ".credentials")sbt publish就能完成上传。
示例流水线脚本(GitLab CI版)
给你一个简化的.gitlab-ci.yml示例,直观展示整个流程:
stages: - checkout-tag - build-test - e2e-test - finalize checkout-and-tag: stage: checkout-tag script: - TAG_NAME="v${CI_PIPELINE_ID}" - git tag -a $TAG_NAME -m "RC for pipeline ${CI_PIPELINE_ID}" - echo "TAG_NAME=$TAG_NAME" > tag.env artifacts: reports: dotenv: tag.env build-and-test: stage: build-test script: - sbt test assembly artifacts: paths: - target/scala-2.13/*.jar e2e-deploy-test: stage: e2e-test script: - scp target/scala-2.13/*.jar test-user@test-server:/opt/my-app/ - ssh test-user@test-server "systemctl restart my-app" - ./run-e2e-tests.sh # 你的E2E测试脚本,失败返回非0状态码 finalize-release: stage: finalize needs: ["e2e-deploy-test"] script: - git push origin $TAG_NAME - jfrog rt upload target/scala-2.13/*.jar my-artefactory-repo/releases/$TAG_NAME/ only: - master # 或者你指定的主分支
内容的提问来源于stack exchange,提问作者Todor Kolev
相关产品推荐
相关产品推荐

