Synesso
Synesso

Reputation: 39018

Setting sbt-pgp passphrase the global configuration in sbt

This page suggests I can add the following to a file in ~/.sbt/*.sbt

pgpPassphrase := Some(Array('a', 'b', 'c'))

When I do I get the error

~/.sbt/pgp.sbt:1: error: reassignment to val
pgpPassphrase := Some(Array('a', 'b', 'c'))
^

I'm not sure how (or if I can) override a setting in SBT.

Upvotes: 3

Views: 783

Answers (3)

Carlos Verdes
Carlos Verdes

Reputation: 3157

With the last version of the plugin I made it running with next steps.

Version used:

addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2")

First add next plugin to have a control on environment variables:

addSbtPlugin("au.com.onegeek" %% "sbt-dotenv" % "2.1.146")

Then create a file .env on your repository (important to add it in your .gitignore, this file should never be in the remote repo)

Inside the file store your passphrase env variable:

PGP_PASSPHRASE="your_passphrase_here"

Then you can try to run again, it should work.

Important to note that is not a recommended setup as someone with access to your machine can get the passphrase easily.

Upvotes: 0

Jane Wayne
Jane Wayne

Reputation: 8855

I'm using sbt 0.13.11. This is what I've done.

In ~/.sbt/plugins I have added this file ~/.sbt/plugins/gpg.sbt. Its content is as follows.

addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0")

In my project's site.sbt, I've added the line.

addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.1")

I've tried to add this line pgpPassphrase := Some(Array('a', 'b', 'c')) to the following locations and they either fail due to syntax or continue to prompt me for a passphrase.

  • ~/.sbt/global.sbt
  • ~/.sbt/0.13/global.sbt

The ONLY way I was able to get the build to stop asking me for a passphrase was to inject it directly into my build.sbt file. For example,

lazy val commonSettings = Seq(
    organization := "com.something",
    version := "0.0.1-SNAPSHOT",
    scalaVersion := "2.10.6",
    publishMavenStyle := true,
    publishTo := {
        val nexus = "http://nexus.something.io/"
        if (isSnapshot.value)
            Some("snapshots" at nexus + "content/repositories/snapshots")
        else
            Some("releases"  at nexus + "content/repositories/releases")
    },
    publishArtifact in Test := false,
    pomIncludeRepository := { _ => false },
    pomExtra := (
            <url>http://gitlab.something.io/something/project</url>
            <scm>
                <url>[email protected]:something/project</url>
                <connection>scm:git:[email protected]:something/project.git</connection>
                <developerConnection>scm:git:[email protected]:something/project.git</developerConnection>
            </scm>
            <developers>
                <developer>
                    <email>[email protected]</email>
                    <name>my name</name>
                    <url>https://github.com/mysite</url>
                    <id>myid</id>
                    <organization>My Org</organization>
                    <organizationUrl>https://github.com/me</organizationUrl>
                </developer>
            </developers>),
    pgpPassphrase := Some(Array('a','b','c'))
)

Alternatively, I was able to define it else where too in build.sbt.

lazy val project = (project in file("."))
      .settings(commonSettings: _*)
      .settings(pgpPassphrase := Some(Array('a','b','c')))
      .settings(name := "my-project")
      .settings(libraryDependencies ++= commonDeps)
      .settings(parallelExecution in Test := false)
      .settings(javaOptions ++= Seq("-Xms512M", "-Xmx2048M", "-XX:MaxPermSize=2048M", "-XX:+CMSClassUnloadingEnabled"))

My weakness is that I don't know enough about SBT, but the documents online do say you can create a file to externalize pgpPassphrase, but it never clearly states how to do so (and that's part of the problem of this post). Empircally, placing/setting pgpPhassphrase in ~/.sbt or ~/.sbt/0.13 does not work.

I suppose I'll be searching for how to externalize values for the .settings() in build.sbt. But if anyone beats me to it, that would be appreciated.

Note: clearly, we should NOT be placing the passphrase in build.sbt (or a file that is versioned in SCM).

Here is somewhat of a workaround #1.

lazy val project = (project in file("."))
      .settings(commonSettings: _*)
      .settings(pgpPassphrase := scala.util.Properties.propOrNone("gpg.passphrase").map(_.toCharArray))
      .settings(name := "my-project")
      .settings(libraryDependencies ++= commonDeps)
      .settings(parallelExecution in Test := false)
      .settings(javaOptions ++= Seq("-Xms512M", "-Xmx2048M", "-XX:MaxPermSize=2048M", "-XX:+CMSClassUnloadingEnabled"))

With this, you can call sbt as follows: sbt -Dgpg.passphrase=abc publish-signed.

Workaround #2.

lazy val project = (project in file("."))
      .settings(commonSettings: _*)
      .settings(pgpPassphrase := Some(System.getenv("GPG_PASSPHRASE").toCharArray))
      .settings(name := "my-project")
      .settings(libraryDependencies ++= commonDeps)
      .settings(parallelExecution in Test := false)
      .settings(javaOptions ++= Seq("-Xms512M", "-Xmx2048M", "-XX:MaxPermSize=2048M", "-XX:+CMSClassUnloadingEnabled"))

With this approach, you'd have to export the passphrase export GPG_PASSPHRASE=abc and then you'd just run sbt publish-signed.

It's interesting to note that if you export your passphrase, the following line doesn't pick up the value (at least in my environment): .settings(pgpPassphrase := scala.util.Properties.envOrNone("GPG_PASSPHRASE").map(_.toCharArray))

I think workaround #2 might be better since you can export the passphrase in your bash profile.

I just found out that inside build.sbt, scala.util.Properties.envOrNone can't find an environment variable like GPG_PASSPHRASE. If I just export something like this export gpg.passphrase=abc, then bash complains. As a middle ground, if I do export gpgpassphrase=abc, then I can do .settings(pgpPassphrase := scala.util.Properties.envOrNone("gpgpassphrase").map(_.toCharArray)) in my build.sbt and simply call sbt publish-signed.

It's interesting to note that in the scala REPL, scala.util.Properties.envOrNone('GPG_PASSPHRASE') does actually work (just not in build.sbt).

Upvotes: 1

Eugene Yokota
Eugene Yokota

Reputation: 95684

setup

With my setup I have ~/.sbt/plugins/plugins.sbt:

addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8")

and ~/.sbt/global.sbt:

pgpPassphrase := Some(Array('a', 'b', 'c')) 

This is probably the same as what you already have.

other issues?

There may be other issues that are loading the sbt-pgp incorrectly. One possibility is that older version of the plugin is still within the classpath. Try cleaning the build project as follows:

> reload plugin
> clean
> reload return

Also make sure that the build you're loading isn't loading sbt-pgp plugin.

Upvotes: 2

Related Questions