Jenkins 2.0:在Docker容器中运行SBT

我有以下Jenkinsfile

 def notifySlack = { String color, String message -> slackSend(color: color, message: "${message}: Job ${env.JOB_NAME} [${env.BUILD_NUMBER}] (${env.BUILD_URL})") } node { try { notifySlack('#FFFF00', 'STARTED') stage('Checkout project') { checkout scm } scalaImage = docker.image('<myNexus>/centos-sbt:2.11.8') stage('Test project') { docker.withRegistry('<myNexus>', 'jenkins-nexus') { scalaImage.inside('-v /var/lib/jenkins/.ivy2:/root/.ivy2') { c -> sh 'sbt clean test' } } } if (env.BRANCH_NAME == 'master') { stage('Release new version') { docker.withRegistry('<myNexus>', 'jenkins-nexus') { scalaImage.inside('-v /var/lib/jenkins/.ivy2:/root/.ivy2') { c -> sh 'sbt release' } } } } notifySlack('#00FF00', 'SUCCESSFUL') } catch (e) { currentBuild.result = "FAILED" notifySlack('#FF0000', 'FAILED') throw e } } 

不幸的是,当我到达sbt clean test线时,我得到了以下错误:

 java.lang.IllegalArgumentException: URI has a query component at java.io.File.<init>(File.java:427) at sbt.IO$.uriToFile(IO.scala:160) at sbt.IO$.toFile(IO.scala:135) at sbt.Classpaths$.sbt$Classpaths$$bootRepository(Defaults.scala:1942) at sbt.Classpaths$$anonfun$appRepositories$1.apply(Defaults.scala:1912) at sbt.Classpaths$$anonfun$appRepositories$1.apply(Defaults.scala:1912) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33) at scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:34) at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) at scala.collection.AbstractTraversable.map(Traversable.scala:105) at sbt.Classpaths$.appRepositories(Defaults.scala:1912) at sbt.Classpaths$$anonfun$58.apply(Defaults.scala:1193) at sbt.Classpaths$$anonfun$58.apply(Defaults.scala:1190) at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47) at sbt.EvaluateSettings$MixedNode.evaluate0(INode.scala:175) at sbt.EvaluateSettings$INode.evaluate(INode.scala:135) at sbt.EvaluateSettings$$anonfun$sbt$EvaluateSettings$$submitEvaluate$1.apply$mcV$sp(INode.scala:69) at sbt.EvaluateSettings.sbt$EvaluateSettings$$run0(INode.scala:78) at sbt.EvaluateSettings$$anon$3.run(INode.scala:74) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) 

如果我运行简单的docker run ...后面的docker exec我得到我想要的,但我想用定义的jenkinsfunction。

所以这似乎是一个SBT问题。 在Docker镜像中使用0.13.16版本。 从我所了解的类path包含一个查询参数SBT:

  • 不喜欢
  • 不知道如何处理
  • 是非法的

我自己没有这样的查询参数,所以我认为这个.inside方法是这样做的。 我检查了容器中的env ,发现RUN_CHANGES_DISPLAY_URL=<my_ip>/job/scheduler/job/fix-jenkins-pipeline/23/display/redirect?page=changes 。 我试图unset它,但没有设法。

我没有想法,我不确定我是否在正确的方向。 任何帮助,将不胜感激。

所以在漫长而乏味的search之后,终于为我工作的是在.sbt容器中明确地设置.sbt.ivy2文件夹。

 sbt -Dsbt.global.base=.sbt -Dsbt.boot.directory=.sbt -Dsbt.ivy.home=.ivy2 clean test 

这不知何故阻止sbt产生? 并直接将上述文件夹放在目录结帐的根目录中。

我花了很多时间来追踪代码

看起来最简单的解决scheme是只传递-Duser.home=<path>到sbt,或者将其设置在SBT_OPTS环境variables中; 那么所有其余的目录将被构build,就像<path>是用户的主目录一样。

我通过设置ivyscaching目录解决了这个问题 – > 如何覆盖常春藤caching的位置?

问题是,它没有设置,默认情况下,它创build一个? 作为回报的文件夹不能由sbt自己处理。

我创build了一个自定义的Dockerfile来对sbt进行更多的控制。 以下是我为解决问题而执行的步骤:

我创build了一个名为ivysettings.xml的文件,内容如下:

 <ivysettings> <properties environment="env" /> <caches defaultCacheDir="/home/jenkins/.ivy2/cache" /> </ivysettings> 

和一个Dockerfile:

 FROM openjdk:8 RUN wget -O- "http://downloads.lightbend.com/scala/2.11.11/scala-2.11.11.tgz" \ | tar xzf - -C /usr/local --strip-components=1 RUN curl -Ls https://git.io/sbt > /usr/bin/sbt && chmod 0755 /usr/bin/sbt RUN adduser -u 1000 --disabled-password --gecos "" jenkins ADD ./files/ivysettings.xml /home/jenkins/.ivy2/ivysettings.xml RUN chown -R jenkins:jenkins /home/jenkins USER jenkins CMD ["sbt"] 

然后我把图片推送到我们的私人docker仓库,我们的pipe道终于可以工作了!