【问题标题】:Split sbt release in stages?分阶段拆分 sbt 发布?
【发布时间】:2018-03-04 20:32:01
【问题描述】:

我有一个 SBT 项目和一个 CD 管道,我想要执行以下步骤序列:

  1. 从 git repo 中签出我的项目
  2. 标记提交
  3. 运行测试
  4. 打包我的应用

现在我还不想发布任何东西,因为我会将二进制文件提升到另一个环境以运行端到端测试。只有当它们成功完成时,我才想推送 git 标签并将我的人工制品上传到远程人工制品存储库。我真正想要实现的是能够首先运行sbt prepereRelease,然后我将提升到我的测试环境,然后,如果一切顺利,再运行sbt doRelease。所以我想要在我的 build.sbt 中有类似的东西:

releaseProcess := Seq[ReleaseStep](
      checkSnapshotDependencies,
      inquireVersions,
      runClean,
      runTest,
      setReleaseVersion,
      commitReleaseVersion,
      tagRelease,
      setNextVersion,
      commitNextVersion
)

commands += Command.command("prepareRelease")((state:State) => {
  val newState = Command.process("release",state)
  println("Release called from prepareRelease...")
  newState
})

releaseProcess := Seq[ReleaseStep](
      publishArtifacts,
      setNextVersion,
      commitNextVersion,
      pushChanges
)

commands += Command.command("doRelease")((state:State) => {
  val newState = Command.process("release",state)
  println("Release called from doRelease...")
  newState
})

我几乎觉得我必须定义两个自定义命令,每个命令都必须使用不同的 releaseProcess 设置从 sbt-release 插件调用原始发布命令 - 这就是我不知道该怎么做的地方去吧。不幸的是,上述设置不起作用,因为releaseProcess 设置会累积步骤,而您最终仍然会同时执行所有步骤。

【问题讨论】:

    标签: scala sbt sbt-release


    【解决方案1】:

    我最终实现它的方式是创建两个自定义命令并将releaseProcess 设置附加到state 对象,然后我将其传递给release 插件:

    // Defines the release process
    releaseIgnoreUntrackedFiles := true
    
    commands += Command.command("prepareRelease")((state: State) => {
      println("Preparing release...")
      val extracted = Project extract state
      val customState = extracted.append(Seq(releaseProcess := Seq[ReleaseStep](
        checkSnapshotDependencies,
        inquireVersions,
        runClean,
        setReleaseVersion,
        commitReleaseVersion,
        tagRelease,
        runTest
      )), state)
      val newState = Command.process("release with-defaults", customState)
      Command.process("dist", newState)
    })
    
    commands += Command.command("completeRelease")((state: State) => {
      println("Completing release...")
      val extracted = Project extract state
      val customState = extracted.append(Seq(releaseProcess := Seq[ReleaseStep](
        inquireVersions,
        setNextVersion,
        commitNextVersion,
        pushChanges
      )), state)
      val newState = Command.process("release with-defaults", customState)
      newState
    })
    

    所以我的管道执行类似于以下的操作:

    1. sbt prepareRelease

    2. 此时我将二进制文件部署到我的 TEST 环境中

    3. 如果一切正常,我会这样做sbt completeRelease

    4. 最终curl我的 zip 进入 nexus

    【讨论】:

    • 我在一个类似的场景中,这个过程很长,必须做这种多步骤的发布过程。但是有一个问题,当主分支中有提交而某个阶段仍在进行中时会发生什么?
    • 一旦您创建了标签,您就可以发布该标签。之后推送到分支的所有内容都将被此特定管道运行忽略。
    【解决方案2】:

    您已将prepareReleasedoRelease 定义为设置。这意味着设置的值只会在加载或重新加载构建时计算一次。此外,ReleaseStep 类型只描述了作为发布过程的一部分执行的函数,它自己不会做任何事情。

    您似乎正在使用sbt-release 插件。按照文档说明,您必须使用自定义步骤重新定义 releaseProcess 键,然后运行 ​​release 命令来执行它们。

    【讨论】:

    • 通过the source,您必须将代码复制到那里并根据您的需要进行调整,因为它不可参数化。
    • 感谢您的评论,我只是想表达我所追求的。我知道如何重新定义 releaseProcess,但在我的情况下,我需要两个单独的命令 - 一个用于准备发布,另一个用于推送所有内容。我几乎觉得我必须定义两个自定义命令,每个命令都必须使用不同的releaseProcess 设置从sbt-release 插件调用原始发布命令——这就是我不知道该怎么做的地方。我已经更新了我的问题以反映这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 2017-12-17
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多