Передайте номер версии при сборке в sbt

У меня есть полусложный процесс SBT, потому что мне нужно условно включить другой файл конфигурации в зависимости от того, какая сборка требуется. Я решил эту проблему с помощью подпроектов:

lazy val app = project
    .in(file("."))
    .enablePlugins(JavaAppPackaging)
    .settings(
      commonSettings // Seq() of settings to be shared between projects
      ,sourceGenerators in Compile += (avroScalaGenerateSpecific in Compile).taskValue
      ,(avroSpecificSourceDirectory in Compile) := new java.io.File("src/main/resources/com/coolCompany/folderName/avro")
    )

lazy val localPackage = project
    .in(file("build/local"))
    .enablePlugins(JavaAppPackaging)
    .settings(
      organization := "com.coolCompany",
      version := "0.1.0-SNAPSHOT",
      scalaVersion := "2.11.8",
      name := "my-neat-project",
      scalacOptions := compilerOptions, //Seq() of compiler flags
      sourceDirectory in Compile := (sourceDirectory in (app, Compile)).value,
      mappings in Universal += {
        ((sourceDirectory in Compile).value / "../../conf/local/config.properties") -> "lib/config.properties"
      }
    )
    .dependsOn(app)

val buildNumber = inputKey[String]("The version number of the artifact.")

lazy val deployedPackage = project
    .in(file("build/deployed"))
    .enablePlugins(JavaAppPackaging)
    .settings(
      organization := "com.coolCompany",
      buildNumber := {
        val args : Seq[String] = spaceDelimited("<arg>").parsed
        println(s"Input version number is ${args.head}")
        args.head
      },
      version := buildNumber.inputTaskValue + "-SNAPSHOT", //"0.1.0-SNAPSHOT",
      scalaVersion := "2.11.8",
      name := "my-cool-project",
      scalacOptions := compilerOptions,
      sourceDirectory in Compile := (sourceDirectory in (app, Compile)).value,
      mappings in Universal += {
        ((sourceDirectory in Compile).value / "../../conf/deployed/config.properties") -> "lib/config.properties"
      }
    )
    .dependsOn(app)

Теперь мне нужно разрешить передачу номера версии инструментом сборки при сборке. Вы можете видеть, что я уже пытался сделать: я создал inputKey задачу с именем buildNumber, а затем попытался получить доступ к ней в определении version :=. Я могу отлично запустить саму задачу buildNumber:

$ sbt 'deployedPackage/buildNumber 0.1.2'
Input version number is 0.1.2

Так что я могу по крайней мере убедиться, что моя задача ввода работает должным образом. Проблема в том, что я не могу понять, как я на самом деле получаю это входное значение при выполнении фактического packageBin шага, который мне нужен.

Я пробовал следующее:

$ sbt 'deployedPackage/universal:packageBin 0.1.2'
[error] Expected key
[error] Expected '::'
[error] Expected end of input.
[error] deployedPackage/universal:packageBin 0.1.2

Так что он явно не понимает, что делать с номером версии. Я пробовал кучу различных вариантов ввода, таких как [...]packageBin buildNumber::0.1.2, [...]packageBin -- buildNumber 0.1.2 или [...]packageBin -- 0.1.2, и все они дают эту ошибку или что-то подобное, что указывает на то, что он не понимает, что я пытаюсь передать.

Теперь, в конечном счете, эти ошибки имеют смысл. buildNumber, задача состоит в том, что знает, что делать со значениями командной строки, а packageBin - нет. Как мне настроить эту задачу или этот набор задач, чтобы разрешить передачу номера версии?

Я видел этот вопрос, но ответы связаны с sbt плагин, который, кажется, делает примерно на 100 вещей больше, чем я хочу, в том числе довольно много, что мне нужно было бы найти способ явно отключить. Я только хочу, чтобы номер версии можно было передать и использовать в артефакте.

Изменить / обновить: я решил эту проблему, вернувшись к Maven.


person Max    schedule 22.12.2017    source источник


Ответы (3)


Я думаю, вы немного запутались в том, как работают настройки sbt. Настройки устанавливаются при загрузке sbt и не могут быть изменены, пока вы не перезагрузите сеанс. Итак, что бы вы ни установили для версии, она будет исправлена, она не может быть динамической и зависеть от пользовательского ввода или задачи (которая, напротив, является динамической и оценивается каждый раз, когда вы ее вызываете).

Это правда. Однако вы все равно можете вычислить значение SettingKey. Мы используем переменные среды для установки нашей версии сборки.

version := "1." + sys.env.getOrElse("BUILD_NUMBER", "0-SNAPSHOT")

Объяснение

  • 1. - это основная версия. Увеличивайте это вручную по своему усмотрению
  • BUILD_NUMBER - это переменная среды, которая обычно устанавливается CI, например Дженкинс. Если не установлен, используйте 0-SNAPSHOT в качестве суффикса версии.

Мы используем это в нашей компании для нашего конвейера непрерывного развертывания.

Надеюсь, это поможет, Муки

person Muki    schedule 31.12.2017
comment
Если вы используете git flow, полезно также использовать https://github.com/sbt/sbt-release или https://github.com/sritchie/sbt-gitflow - person mgosk; 31.01.2018

Я думаю, вы немного запутались в том, как работают настройки sbt. Настройки устанавливаются при загрузке sbt и не могут быть изменены, пока вы не перезагрузите сеанс. Итак, что бы вы ни установили для version, оно будет исправлено, оно не может быть динамическим и зависеть от ввода пользователя или задачи (которая, напротив, является динамической и оценивается каждый раз, когда вы ее вызываете).

У вас есть задача ввода buildNumber, которая зависит от ввода пользователя и оценивается каждый раз, когда вы ее вызываете:

> show buildNumber 123
Input version number is 123
[info] 123
[success] Total time: 0 s, completed Dec 24, 2017 3:41:43 PM
> show buildNumber 456
Input version number is 456
[info] 456
[success] Total time: 0 s, completed Dec 24, 2017 3:41:45 PM

Он возвращает все, что вы ему даете, и ничего не делает (кроме println). Что еще более важно, это никак не влияет на version настройку (и даже теоретически не может).

Когда вы используете buildNumber.inputTaskValue, вы ссылаетесь на саму задачу ввода, а не на ее значение (которое неизвестно, потому что оно зависит от ввода пользователя). Вы можете увидеть это, проверив значение настройки version:

> show version
[info] sbt.InputTask@6c996907-SNAPSHOT

Так что это точно не то, что вам нужно.


Я предлагаю вам пересмотреть свой подход в целом и прочитать еще немного документации по sbt, например о График задач (и всю главу" Начало работы ").

Если вам все еще действительно нужно установить версию при загрузке sbt в соответствии с вашими данными, вы можете сделать это с помощью команда. Это выглядело бы так:

commands += Command.single("pkg") { (state0, buildNumber) =>
  val state1 = Project.extract(state0).append(Seq(version := buildNumber + "-SNAPSHOT"), state0)
  val (state2, result) = Project.extract(state1).runTask(packageBin in (deployedPackage, universal), state1)
  state2
}

Но вы должны быть очень осторожны, работая с состоянием вручную. Опять же, я рекомендую вам пересмотреть свой подход и изменить его на более sbt-идиоматический.

person laughedelic    schedule 24.12.2017
comment
Я не удивлен, что делаю это неправильно. Есть ли отправная точка для такого рода вещей? Я удивлен тем, как мало ресурсов я могу найти для того, что, по моему мнению, будет чрезвычайно распространенным вариантом использования. - person Max; 26.12.2017
comment
Я связал документацию sbt в ответе. К сожалению, больше нечего читать. Вы также можете попросить на канале Gitter решить некоторые небольшие проблемы. - person laughedelic; 29.12.2017

Я предлагаю вам просто установить параметр версии только для проекта deployedPackage непосредственно перед вызовом задачи, которой требуется версия. Это самый простой способ установки версии, и, поскольку ключи настроек имеют области действия, это должно работать должным образом.

Я использовал что-то подобное для большого многомодульного проекта, в котором один из проектов имел отдельную историю версий, чем другие проекты.

person Wolfgang Liebich    schedule 16.03.2018
comment
Я бы перефразировал это как реальный ответ или опубликовал как комментарий. В нынешнем виде этот вопрос, вероятно, будет воспринят как не ответ и поэтому будет отмечен соответствующим образом. - person Filnor; 16.03.2018