简体   繁体   中英

How do I add an SBT plugin resolver on CircleCI?

I am trying to automate CI/CD of a small Scala project using CircleCI. The project is built using sbt , and tested using the ScalaTest library.

As per the ScalaTest installation instruction's recommendation, I am using the SuperSafe compiler plugin, which required me to add a resolver to global file ~/.sbt/1.0/global.sbt :

resolvers += "Artima Maven Repository" at "http://repo.artima.com/releases"

I can successfully compile and test my project locally. however on CircleCI the build fails with error:

[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: com.artima.supersafe#supersafe_2.12.8;1.1.7: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn] 
[warn]  Note: Unresolved dependencies path:
[warn]      com.artima.supersafe:supersafe_2.12.8:1.1.7 (Defaults.scala#L3331)
[warn]        +- filesystem:filesystem_2.12:0.1
[error] sbt.librarymanagement.ResolveException: unresolved dependency: com.artima.supersafe#supersafe_2.12.8;1.1.7: not found
[error]     at sbt.internal.librarymanagement.IvyActions$.resolveAndRetrieve(IvyActions.scala:332)
[error]     at sbt.internal.librarymanagement.IvyActions$.$anonfun$updateEither$1(IvyActions.scala:208)
[error]     at sbt.internal.librarymanagement.IvySbt$Module.$anonfun$withModule$1(Ivy.scala:239)
[error]     at sbt.internal.librarymanagement.IvySbt.$anonfun$withIvy$1(Ivy.scala:204)
[error]     at sbt.internal.librarymanagement.IvySbt.sbt$internal$librarymanagement$IvySbt$$action$1(Ivy.scala:70)
[error]     at sbt.internal.librarymanagement.IvySbt$$anon$3.call(Ivy.scala:77)
[error]     at xsbt.boot.Locks$GlobalLock.withChannel$1(Locks.scala:95)
[error]     at xsbt.boot.Locks$GlobalLock.xsbt$boot$Locks$GlobalLock$$withChannelRetries$1(Locks.scala:80)
[error]     at xsbt.boot.Locks$GlobalLock$$anonfun$withFileLock$1.apply(Locks.scala:99)
[error]     at xsbt.boot.Using$.withResource(Using.scala:10)
[error]     at xsbt.boot.Using$.apply(Using.scala:9)
[error]     at xsbt.boot.Locks$GlobalLock.ignoringDeadlockAvoided(Locks.scala:60)
[error]     at xsbt.boot.Locks$GlobalLock.withLock(Locks.scala:50)
[error]     at xsbt.boot.Locks$.apply0(Locks.scala:31)
[error]     at xsbt.boot.Locks$.apply(Locks.scala:28)
[error]     at sbt.internal.librarymanagement.IvySbt.withDefaultLogger(Ivy.scala:77)
[error]     at sbt.internal.librarymanagement.IvySbt.withIvy(Ivy.scala:199)
[error]     at sbt.internal.librarymanagement.IvySbt.withIvy(Ivy.scala:196)
[error]     at sbt.internal.librarymanagement.IvySbt$Module.withModule(Ivy.scala:238)
[error]     at sbt.internal.librarymanagement.IvyActions$.updateEither(IvyActions.scala:193)
[error]     at sbt.librarymanagement.ivy.IvyDependencyResolution.update(IvyDependencyResolution.scala:20)
[error]     at sbt.librarymanagement.DependencyResolution.update(DependencyResolution.scala:56)
[error]     at sbt.internal.LibraryManagement$.resolve$1(LibraryManagement.scala:45)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$12(LibraryManagement.scala:93)
[error]     at sbt.util.Tracked$.$anonfun$lastOutput$1(Tracked.scala:68)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$19(LibraryManagement.scala:106)
[error]     at scala.util.control.Exception$Catch.apply(Exception.scala:224)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$11(LibraryManagement.scala:106)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$11$adapted(LibraryManagement.scala:89)
[error]     at sbt.util.Tracked$.$anonfun$inputChanged$1(Tracked.scala:149)
[error]     at sbt.internal.LibraryManagement$.cachedUpdate(LibraryManagement.scala:120)
[error]     at sbt.Classpaths$.$anonfun$updateTask$5(Defaults.scala:2561)
[error]     at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]     at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:40)
[error]     at sbt.std.Transform$$anon$4.work(System.scala:67)
[error]     at sbt.Execute.$anonfun$submit$2(Execute.scala:269)
[error]     at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]     at sbt.Execute.work(Execute.scala:278)
[error]     at sbt.Execute.$anonfun$submit$1(Execute.scala:269)
[error]     at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
[error]     at sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
[error]     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error]     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error]     at java.lang.Thread.run(Thread.java:748)
[error] (update) sbt.librarymanagement.ResolveException: unresolved dependency: com.artima.supersafe#supersafe_2.12.8;1.1.7: not found

This error is to be expected when the required resolver hasn't been added in SBT -- see eg this issue . I am new to CircleCI and don't know where its SBT globals dir would be located, or how to modify the file.

Instead I've tried to add the resolver to my project's ./project/plugins.sbt file directly, but this has not fixed the issue.

The SBT and CircleCI config files look as follows:

./build.sbt

name := "my-project-name"

version := "0.1"

scalaVersion := "2.12.8"

libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.8"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % "test"

./project/build.properties

sbt.version = 1.2.8

./project/plugins.sbt

resolvers += "Artima Maven Repository" at "http://repo.artima.com/releases"

addSbtPlugin("com.artima.supersafe" % "sbtplugin" % "1.1.7")

./.circleci/config.yml (the default Scala config provided by CircleCI)

# Scala CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/sample-config/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/openjdk:8-jdk

      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/postgres:9.4

    working_directory: ~/repo

    environment:
      # Customize the JVM maximum heap limit
      JVM_OPTS: -Xmx3200m
      TERM: dumb

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "build.sbt" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      - run: cat /dev/null | sbt test:compile

      - save_cache:
          paths:
            - ~/.m2
          key: v1-dependencies--{{ checksum "build.sbt" }}

      # run tests!
      - run: cat /dev/null | sbt test:test

I want a successful CircleCI build, which will require a way to add the resolver, either in the project's own files or declaring it in the SBT globals file of the CircleCI container.

Consider open issue SBT isn't using resolvers defined in project/plugins.sbt #4103 . Try scoping the resolver to ThisBuild and put it in both build.sbt and plugins.sbt like so:

// someApp/build.sbt
resolvers in ThisBuild += "Artima Maven Repository" at "http://repo.artima.com/releases"

and

// someApp/project/plugins.sbt
resolvers in ThisBuild += "Artima Maven Repository" at "http://repo.artima.com/releases"
addSbtPlugin("com.artima.supersafe" % "sbtplugin" % "1.1.7")

This seems to have worked on this example repo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM