默认情况下,发布的工件是主二进制 jar、包含主源代码和资源的 jar 以及包含 API 文档的 jar。您可以添加测试类、源代码或 API 的工件,也可以禁用一些主工件。
要添加所有测试工件
lazy val app = (project in file("app"))
  .settings(
    Test / publishArtifact := true,
  )
要分别添加它们
lazy val app = (project in file("app"))
  .settings(
    // enable publishing the jar produced by `Test/package`
    Test / packageBin / publishArtifact := true,
    // enable publishing the test API jar
    Test / packageDoc / publishArtifact := true,
    // enable publishing the test sources jar
    Test / packageSrc / publishArtifact := true,
  )
要分别禁用主工件
lazy val app = (project in file("app"))
  .settings(
    // disable publishing the main jar produced by `package`
    Compile / packageBin / publishArtifact := false,
    // disable publishing the main API jar
    Compile / packageDoc / publishArtifact := false,
    // disable publishing the main sources jar
    Compile / packageSrc / publishArtifact := false,
  )
除了 publishArtifact 之外,每个内置工件都有一些可配置的设置。基本设置是 artifact(类型为 SettingKey[Artifact])、mappings(类型为 TaskKey[(File, String)])和 artifactPath(类型为 SettingKey[File])。它们按 (Config / <task>) 范围划分,如上一节所述。
要修改主工件的类型,例如
Compile / packageBin / artifact := {
  val prev: Artifact = (Compile / packageBin / artifact).value
  prev.withType("bundle")
}
生成的工件名称由 artifactName 设置决定。此设置的类型为 (ScalaVersion, ModuleID, Artifact) => String。ScalaVersion 参数提供完整的 Scala 版本字符串和版本的二进制兼容部分字符串。字符串结果是生成的要生成的文件的名称。默认实现是 Artifact.artifactName _。可以修改函数以生成不同的本地名称,而不会影响发布名称,发布名称由 artifact 定义和仓库模式组合决定。
例如,要生成没有分类器或交叉路径的最小名称
artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
  artifact.name + "-" + module.revision + "." + artifact.extension
}
(请注意,在实践中您很少想删除分类器。)
最后,您可以通过映射 packagedArtifact 任务获取 (Artifact, File) 对。请注意,如果您不需要 Artifact,则可以从 package 任务(package、packageDoc 或 packageSrc)中获取 File。在这两种情况下,映射任务以获取文件可确保首先生成工件,因此文件保证是最新的。
例如
val myTask = taskKey[Unit]("My task.")
myTask :=  {
  val (art, file) = (Compile / packageBin / packagedArtifact).value
  println("Artifact definition: " + art)
  println("Packaged file: " + file.getAbsolutePath)
}
除了配置内置工件外,您还可以声明其他要发布的工件。在使用 Ivy 元数据时允许使用多个工件,但 Maven POM 文件只支持根据分类器区分工件,而这些分类器不会记录在 POM 中。
基本 Artifact 构造看起来像
Artifact("name", "type", "extension")
Artifact("name", "classifier")
Artifact("name", url: URL)
Artifact("name", Map("extra1" -> "value1", "extra2" -> "value2"))
例如
Artifact("myproject", "zip", "zip")
Artifact("myproject", "image", "jpg")
Artifact("myproject", "jdk15")
有关工件的更多详细信息,请参见 Ivy 文档。有关组合上述参数和指定 [配置] 和额外属性的信息,请参见 Artifact API。
要声明这些工件以进行发布,请将它们映射到生成工件的任务
val myImageTask = taskKey[File](...)
myImageTask := {
  val artifact: File = makeArtifact(...)
  artifact
}
addArtifact(Artifact("myproject", "image", "jpg"), myImageTask)
addArtifact 返回一系列设置(包装在 SettingsDefinition 中)。在完整的构建配置中,用法如下
lazy val app = (project in file("app"))
  .settings(
    addArtifact(...)
  )
Web 应用程序的常见用例是发布 .war 文件而不是 .jar 文件。
lazy val app = (project in file("app"))
  .settings(
    // disable .jar publishing
    Compile / packageBin / publishArtifact := false,
    // create an Artifact for publishing the .war file
    Compile / packageWar / artifact := {
      val prev: Artifact = (Compile / packageWar / artifact).value
      prev.withType("war").withExtension("war")
    },
    // add the .war file to what gets published
    addArtifact(Compile / packageWar / artifact, packageWar),
  )
要指定要从具有自定义或多个工件的依赖项中使用的工件,请在依赖项上使用 artifacts 方法。例如
libraryDependencies += ("org" % "name" % "rev").artifacts(Artifact("name", "type", "ext"))
from 和 classifer 方法(在 库管理 页面上描述)实际上是便利方法,它们会转换为 artifacts
def from(url: String) = artifacts(Artifact(name, new URL(url)))
def classifier(c: String) = artifacts(Artifact(name, c))
也就是说,以下两个依赖项声明是等效的
libraryDependencies += ("org.testng" % "testng" % "5.7").classifier("jdk15")
libraryDependencies += ("org.testng" % "testng" % "5.7").artifacts(Artifact("testng", "jdk15"))