Code Monkey home page Code Monkey logo

sbt-pgp's Introduction

sbt-pgp

sbt-pgp provides PGP signing for sbt.

Some OSS repositories (e.g. Sonatype) will require that you sign artifacts with publicly available keys prior to release. The primary purpose of sbt-pgp is to let you sign the artifacts using a GPG key.

Setup

sbt-pgp Scala version support

Add the following to your project/plugins.sbt file:

addSbtPlugin("com.github.sbt" % "sbt-pgp" % "x.y.z")

Note: We changed the organization from "com.jsuereth" to "com.github.sbt".

Usage

There are two modes of use:

  • By default sbt-pgp 2.0.0+ will use the gpg command-line utility (GNU Privary Guard, "GnuPG"). It provides great support and is available on many platforms. You'll need to make sure this is installed prior to usage as this dependency is not provided.
  • Prior to sbt-pgp 2.0.0, sbt-pgp used the Bouncy Castle library, an implementation of PGP that is included with the plugin. It is a Java-only solution that gives the plugin great flexibility in what it can do and how it performs it.

Install GnuPG (or GNU Privacy Guard, GPG)

First, please check that you have a recent version of GPG (GNU Privary Guard, "GnuPG") on your system. If not, install it from http://www.gnupg.org/download/ or your favorite package manager. For macOS, we recommend using GPG Suite.

$ gpg --version
gpg (GnuPG/MacGPG2) 2.2.17
libgcrypt 1.8.4
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /Users/xxxx/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

You should also have a program named gpg-agent running in the background.

$ ps aux | grep gpg
eed3si9n          5157   0.0  0.0  4317860    972   ??  Ss    7:17PM   0:00.02 gpg-agent --homedir /Users/eed3si9n/.gnupg --use-standard-socket --daemon
eed3si9n          2734   0.0  0.0  4300360    732   ??  S     6:56PM   0:00.02 /bin/bash /usr/local/MacGPG2/libexec/shutdown-gpg-agent
eed3si9n          5291   0.0  0.0  4277252    824 s002  S+    7:24PM   0:00.00 grep gpg

If you're using GPG Suite, navigate to Preferences > GPG Suite, and uncheck "Store in macOS Keychain" to prevent your passphrase from being stored on your laptop.

Working with PGP signatures

See Working with PGP Signatures for details.

A key pair allows you to sign artifacts with GPG and users can subsequently validate that artifacts have been signed by you. You can generate a key with.

$ gpg --gen-key

Select the default value when asked for the kind (RSA) and the size (2048bit) of the key. The time of validity for the key defaults to never expire. However it is commonly suggested to use a value of less than 2 years. Once they key is expired you can extend it, provided you own the key and therefore know the passphrase.

Once key pair is generated, we can list them along with any other keys installed:

$ gpg --list-keys
/Users/xxx/.gnupg/pubring.gpg
----------------------------------
pub   dsa2048 2010-08-19 [SC] [expires: 2020-06-15]
      85E38F69046B44C1EC9FB07B76D78F0500D026C4
uid           [ultimate] GPGTools Team <[email protected]>
uid           [ultimate] GPGTools Project Team (Official OpenPGP Key) <[email protected]>
uid           [ultimate] GPGMail Project Team (Official OpenPGP Key) <[email protected]>
uid           [ultimate] [jpeg image of size 5871]
sub   elg2048 2010-08-19 [E] [expires: 2020-06-15]
sub   rsa4096 2014-04-08 [S] [expires: 2024-01-02]

pub   rsa2048 2012-02-14 [SCEA] [expires: 2028-02-09]
      2BE67AC00D699E04E840B7FE29967E804D85663F
uid           [ultimate] Eugene Yokota <[email protected]>
sub   rsa2048 2012-02-14 [SEA] [expires: 2028-02-09]

....

To list the private keys you can use:

$ gpg --list-secret-keys
/Users/xxx/.gnupg/pubring.gpg
----------------------------------
sec   rsa2048 2012-02-14 [SCEA] [expires: 2028-02-09]
      2BE67AC00D699E04E840B7FE29967E804D85663F
uid           [ultimate] Eugene Yokota <[email protected]>
ssb   rsa2048 2012-02-14 [SEA] [expires: 2028-02-09]

Since other people need your public key to verify your files, you have to distribute your public key to a key server:

$ gpg --keyserver keyserver.ubuntu.com --send-keys 2BE67AC00D699E04E840B7FE29967E804D85663F

Importing key pair

If you have previously created a key pair using sbt-pgp 1.x's pgp-cmd for example, your secret key should be at $HOME/.sbt/gpg/secring.asc. You can import this to GnuPG as follows:

$ gpg --import $HOME/.sbt/gpg/secring.asc
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 77098E6A92692949: public key "foo <[email protected]>" imported
gpg: key 77098E6A92692949: secret key imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg:       secret keys read: 1
gpg:   secret keys imported:

gpg --list-key
/root/.gnupg/pubring.kbx
------------------------
pub   rsa2048 2019-09-15 [SCEA]
      965F25CC72DF4F2A4358AC9B77098E6A92692949
uid           [ unknown] foo <[email protected]>

Next, see signing key section below to set 965F25CC72DF4F2A4358AC9B77098E6A92692949 as the signing key.

Publishing from Travis CI

See sbt-ci-release.

Publishing Artifacts

To publish signed artifacts, use publishSigned or publishLocalSigned.

Skipping publishing

To skip the publish step for a subproject, set publish / skip to true.

publish / skip := true

PIN entry (passphrase entry)

If you've configured your gpg-agent with GPG Suite, it should ask for the passphrase when you run publishLocalSigned:

pinentry

Note: It might take 30s or more for the dialog to show up.

Otherwise, add pinentry-program line in ~/.gnupg/gpg-agent.conf with the appropriate path to a pinentry program:

pinentry-program /usr/bin/pinentry
default-cache-ttl 600
max-cache-ttl 7200

You might need to restart the gpg-agent for the setting to take effect.

Automating PIN entry (passphrase Entry)

sbt-pgp 1.x has provided ways of storing passphrase using pgpPassphrase or in the credentials, but we no longer recommend using these methods on your laptop.

On CI environment like Travis CI, you might want to automate passphrase entry. For that purpose sbt-pgp supports PGP_PASSPHRASE environment variable following olafurpg/sbt-ci-release.

Configuration: Signing Key

By default, all signing operations will use gpg's default key. A specific key can be used by setting sbt Credentials for the host "gpg".

credentials += Credentials(
  "GnuPG Key ID",
  "gpg",
  "2BE67AC00D699E04E840B7FE29967E804D85663F", // key identifier
  "ignored" // this field is ignored; passwords are supplied by pinentry
)

Note: This follows the convention set by jodersky/sbt-gpg.

You can also use the usePgpKeyHex method.

usePgpKeyHex("2BE67AC00D699E04E840B7FE29967E804D85663F")

OpenPGP Support

If you are using a Yubikey 4 or another smartcard that supports OpenPGP, then you may have private keys implemented directly on the smartcard rather than using the gpg keyring. In this situation, you will use gpg-agent and a pinentry (pinentry-mac, pinentry-qt, pinentry-curses etc) rather than a passphrase. Set useGpgPinentry := true in your build.sbt settings to configure sbt-pgp appropriately.

Global / useGpgPinentry := true

Note that sbt-pgp only supports OpenPGP through the GPG command line tool -- it is not available through bouncycastle. In addition, you may need to explicitly enable support for OpenPGP on the Yubikey 4.

Configuration: gpg command-line

sbt-pgp needs to know where the gpg executable is to run. It will look for a either a gpg or gpg.exe executable on your PATH depdending on your platform. To configure a different location, place the following in your ~/.sbt/gpg.sbt file:

Global / gpgCommand := "/path/to/gpg"

By default sbt-pgp will use the default private keys from the standard gpg keyrings. You can configure the key ring you use with the pgpKeyRing setting.

Global / pgpKeyRing := Some(file("/home/me/pgp/pubring.gpg"))

If specificied, this is passed to gpg command as --no-default-keyring --keyring <value>.

Validating PGP Keys

The plugin can be used to validate the PGP signatures of the dependencies of the project you're using. To validate these signatures, simply use the checkPgpSignatures task:

> checkPgpSignatures
[info] Resolving org.scala-lang#scala-library;2.9.1 ...
...
[info] ----- PGP Signature Results -----
[info]                    com.novocode : junit-interface :        0.7 : jar   [MISSING]
[info]               javax.transaction :             jta :     1.0.1B : jar   [MISSING]
[info]          org.scala-lang.plugins :   continuations :      2.9.1 : jar   [MISSING]
[info]                org.apache.derby :           derby : 10.5.3.0_1 : jar   [UNTRUSTED(0x98e21827)]
[error] {file:/home/josh/projects/typesafe/test-signing/}test-gpg/*:check-pgp-signatures: Some artifacts have bad signatures or are signed by untrusted sources!
[error] Total time: 2 s, completed Jan 23, 2012 12:03:28 PM

In the above output, the signature for derby is from an untrusted key (id: 0x98e21827). You can import this key into your public key ring, and then the plugin will trust artifacts from that key. The public, by default, accepts any keys included in your public key ring file.

Using Bouncy Castle (deprecated)

Prior to sbt-pgp 2.0.0, sbt-pgp used the Bouncy Castle library by default. If you cant to use gpg command setting useGpg to false will use the Bouncy Castle mode:

Global / useGpg := false

Or by setting SBT_PGP_USE_GPG environment variable to 0.

When using Bouncy Castle modue, sbt-pgp will ask for your password once, and cache it for the duration of the sbt process. The prompt will look something like this:

Please enter PGP passphrase (or ENTER to abort): ******

sbt-pgp's People

Contributors

cvogt avatar dwijnand avatar eed3si9n avatar fmpwizard avatar fthomas avatar gitter-badger avatar graingert avatar havocp avatar jroper avatar jsuereth avatar matthewfarwell avatar mshibuya avatar pfn avatar pvlugter avatar raboof avatar remi-thieblin-ck avatar rhpvorderman avatar rossabaker avatar rslifka avatar sethtisue avatar sirthias avatar sovaalexandr avatar thebizzle avatar winitzki avatar wsargent avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

sbt-pgp's Issues

Key collisions when used as a global plugin

[error] AttributeKey ID collisions detected for: 'pgp-signer' (sbt.Task[com.jsuereth.pgp.sbtplugin.PgpSigner], sbt.Task[com.jsuereth.pgp.sbtplugin.PgpSigner]), 'pgp-verifier' (sbt.Task[com.jsuereth.pgp.sbtplugin.PgpVerifier], sbt.Task[com.jsuereth.pgp.sbtplugin.PgpVerifier]), 'pgp-context' (sbt.Task[com.jsuereth.pgp.cli.PgpCommandContext], sbt.Task[com.jsuereth.pgp.cli.PgpCommandContext]), 'check-pgp-signatures' (sbt.Task[com.jsuereth.pgp.sbtplugin.SignatureCheckReport], sbt.Task[com.jsuereth.pgp.sbtplugin.SignatureCheckReport]), 'pgp-static-context' (com.jsuereth.pgp.cli.PgpStaticContext, com.jsuereth.pgp.cli.PgpStaticContext), 'signatures-module' (sbt.Task[com.jsuereth.pgp.sbtplugin.GetSignaturesModule], sbt.Task[com.jsuereth.pgp.sbtplugin.GetSignaturesModule])

Maybe I'm doing something wrong. I thought this was fixed when I switched the sbt-extras script but it was just that I wasn't loading the gpg plugin at all. Now I have this

resolvers ++= Seq(
  Resolver.url("sbt-plugin-releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
)

addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6")

in ~/.sbt/0.11.2/plugins/build.sbt

Pick up GnuPG's default key setting

Choosing the first key in the key ring isn't always a great default. With GnuPG a default key can be specified in ~/.gnupg/gpg.conf with the entry default-key (if set).

Trying to include v0.6 of the plugin in project/plugins.sbt fails

[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: commons-logging#commons-logging;1.1.1: configuration not found in commons-logging#commons-logging;1.1.1: 'compile'. It was required from org.apache.httpcomponents#httpclient;4.1.2 compile
[warn] ::::::::::::::::::::::::::::::::::::::::::::::

My plugins.sbt file:
// IDEA plugin
resolvers += "sbt-idea-repo" at "http://mpeltonen.github.com/maven/"

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.0.0")

resolvers += Resolver.url("Typesafe repository", new java.net.URL("http://typesafe.artifactoryonline.com/typesafe/ivy-releases/"))(Resolver.defaultIvyPatterns)

libraryDependencies <+= (sbtVersion) { sv =>
"org.scala-sbt" %% "scripted-plugin" % sv
}

resolvers += Resolver.url("scalasbt", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns)

addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6")

Using v0.5 works fine.

PGPException after passphrase

I'm getting a:

org.bouncycastle.openpgp.PGPException: Exception creating cipher

Right after I enter my passphrase. Interestingly, I have useGpg := true in my build, so I'm not sure why BouncyCastle is even being used. My signing key is http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xB65777EC21A7FB53, and GPG works fine from the command line. pgp-cmd works fine, too, from inside SBT, as long as I just want to list-keys.

This is SBT 0.11.3 with plugin version 0.6.

Thanks,

Derek

SBT 0.13: publish-signed is publishing gpg plugin dependencies

During the publishSigned phase in SBT 0.13.5, all custom dependencies defined in ~/.sbt/0.13/plugins.sbt and ~/.sbt/0.13/gpg.sbt are added to the extra dependencies in the generated pom.xml during Maven style publishing.

To reproduce this, you can have a look at "com.websudos" %% "phantom-dsl" % "1.2.0", the project is found here and the build definition here.

This effectively leads to this issue, for all framework users:

Note: Some unresolved dependencies have extra attributes.  Check that these dependencies exist with the requested attributes.
[warn]      com.typesafe.sbt:sbt-pgp:0.8.1 (sbtVersion=0.13, scalaVersion=2.10)

Please update bouncycastle dependency

Many apis in bouncycastle have changed from 1.47 and up.

I have a newer plugin that requires the newer apis, and as a result; sbt-pgp conflicts with this plugin and is unable to be used in conjunction with it.

Please update the dependency on bcpg to be "org.bouncycastle" % "bcpg-jdk15on" % "1.48"

Password caching is terrifying

As per discussion…

I think this is a problem that we need to solve at the SBT level, since it's actually SBT that controls the SecurityManager. Fixing this problem in a general way at the SBT level would also give us a general tool for use in other areas, such as credentials and stuff like my 1Password trick.

A solution at the SBT level should look something like this:

trait SecureCache {
  def put[Client: ClassTag](key: Key)(value: key.Value): Unit
  def get(key: Key): Option[key.Value]

  trait Key {
    type Value

    final override def hashCode = System.identityHashCode(this)
    final override def equals(that: Any) = this eq that
  }
}

I'm using dependent method types here just to make the API slightly nicer on the client side, since tossing an extra type parameter in there would require over-specification of type information. Lots of stuff you can do there (also, if you want to be gross, you can always take a second ClassTag and use a String key).

Anyway, the Client tag is taken by the put function to restrict access. Whenever the get method is called, we should interrogate Thread.currentThread.getStackTrace in order to ensure that we're actually accessing the data from either the Client class or an inner class thereof (including lambdas). Note that we need to look at the immediately previous stack frame entry and validate the access there (hence the constraint about inner classes). If we just walk arbitrarily far up the stack trace, looking for any instance of Client, we open up a security hole.

Here's where the SecurityManager comes in… Reflective access of any kind to the implementation of SecureCache must be prevented. Furthermore, the SBT SecurityManager needs to forbid installation of custom security managers which could override these restrictions (it doesn't currently, which actually allows plugins to do devious things with the current security manager). Note that SecureCache can and probably should do some extra checking inside of put to ensure that it is specifically SBT's SecurityManager that is installed, bailing out without storing the data if the check is failed. We don't want someone doing something tricky by forking a subprocess instance of SBT with a custom security manager that overrides SBT's default.

Obviously this isn't fool-proof. There are plenty of threat vectors which this doesn't prevent. Heck, just taking a heap dump (can you forbid that with a SecurityManager?) seems like a pretty direct way to read this information, but trickier things like core dumps also seem like a possibility. At the end of the day, SBT is a build tool, and build tools are all about forking arbitrary and unrestricted subprocesses. We can make things harder though, and that's all security is about.

So to summarize, SecureCache provided by SBT as part of the core framework and protected by SBT's SecurityManager would give plugins (and builds!) the ability to stash data in memory in such a way that it is very hard (but not impossible) to exfiltrate. We could probably also offer some nice APIs on top of this for doing things like prompting for passwords and automatically storing them in SecureCache, but that's just gravy. Having SecureCache in the first place is the important bit.

Docs: "key id" and/or "hex key ID"

Following along here:

http://www.scala-sbt.org/sbt-pgp/usage.html

At the very last step ("Export your public key") unsure where to find what's referred to as the your key id and/or hex key ID. Dug through the source, hoping to find a task (and happy to author one) that would print out all of your PGP-plugin related settings, and that that would include the key ID :)

Any pointers?

Thanks!

Upgrade to bouncycastle 1.51 and stop using deprecated methods

sbt-pgp blows up when other packages (such as Play 2.3.3) pull in newer versions of bouncycastle. This is because sbt-pgp is using deprecated methods that were removed in 1.51.

E.g. instead of using PGPKeyPair we should be using BcPGPKeyPair or JcaPGPKeyPair as appropriate.

This is why it's bad to ignore deprecation warnings ;-)

Can't launch sbt because of ".sbt/0.13/plugins/gpg.sbt:3: error: not found: value pgpSecretRing" error

I have pgpSecretRing and phpPubRing already generated by PGP UI tool. I have created ~/.sbt/0.13/plugins/pgp.sbt file and have put there next content :

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

pgpSecretRing := file("/Users/biercoff/.gnupg/secring.gpg")

pgpPublicRing := file("/Users/biercoff/.gnupg/pubring.gpg")

When i try to run sbt in my project, i get next error :

➜  fabricator git:(master) sbt
/Users/biercoff/.sbt/0.13/plugins/gpg.sbt:3: error: not found: value pgpSecretRing
pgpSecretRing := file("/Users/biercoff/.gnupg/secring.gpg")
^
[error] Type error in expression
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?

What am i missing ?

Exception when using plugin with SBT 0.12.1`

Hi,

I'm using version 0.7 with SBT 0.12.1, and as soon as I add any plugin specific settings in my ~/.sbt/user.sbt

I get: java.lang.NoClassDefFoundError: com/typesafe/sbt/SbtPgp$

When launching SBT :-(

Thanks

Can't publishLocalSigned on banana-rdf

I can't publishLocalSigned with banana-rdf (changeset e636b06f2cc92bca). I was initially trying to release using sbt-release but I hit a similar issue.

> show */*:pgpSecretRing
[info] /home/betehess/.gnupg/secring.gpg
> show */*:pgpPublicRing
[info] /home/betehess/.gnupg/pubring.gpg

The two files exist:

$ ls -l /home/betehess/.gnupg/secring.gpg /home/betehess/.gnupg/pubring.gpg
-rw------- 1 betehess betehess 3888 Feb 21 14:33 /home/betehess/.gnupg/pubring.gpg
-rw------- 1 betehess betehess 2580 Jan 23 17:33 /home/betehess/.gnupg/secring.gpg

I can check that my passphrase is ok:

$ echo "1234" | gpg --no-use-agent -o /dev/null --local-user 'Alexandre Bertails <[email protected]>' --no-greeting -as - && echo "The correct passphrase was entered for this key"

You need a passphrase to unlock the secret key for
user: "Alexandre Bertails <[email protected]>"
2048-bit RSA key, ID 783C0995, created 2015-01-23

The correct passphrase was entered for this key

Then when I publishLocalSigned I get

[trace] Stack trace suppressed: run last banana/*:signedArtifacts for the full output.
[trace] Stack trace suppressed: run last examples/*:signedArtifacts for the full output.
[error] (banana/*:signedArtifacts) java.io.FileNotFoundException:  (No such file or directory)
[error] (examples/*:signedArtifacts) java.io.FileNotFoundException:  (No such file or directory)

and

> last banana/*:signedArtifacts examples/*:signedArtifacts java.io.FileNotFoundException: (No such file or directory) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.<init>(FileInputStream.java:146) at com.jsuereth.pgp.SecretKey.sign(PrivateKey.scala:55)

Configured secret ring is not fed to GPG when forking GPG.

I've confirmed that I can do a publish-signed on my local box. I then configured project/Build.sbt with the following:

      useGpg := true,
      usePgpKeyHex("FEEA9B39"),
      pgpSecretRing := file("/home/travis/build/intel-hadoop/gearpump/secring.asc"),

In .travis.yml I defined the before_install to extract the secret key

before_install:
- if [[ $TRAVIS_PULL_REQUEST == "false" ]]; then openssl aes-256-cbc -K $encrypted_6014e4216d04_key -iv $encrypted_6014e4216d04_iv -in secring.asc.enc -out /home/travis/build/intel-hadoop/gearpump/secring.asc -d;ls -l /home/travis/build/intel-hadoop/gearpump/secring.asc;fi

As shown below where I do a 'ls -l', the secret key is extracted successfully

travis_fold:start:before_install.1
�[0Ktravis_time:start:0da34dd4
�[0K$ if [[ $TRAVIS_PULL_REQUEST == "false" ]]; then openssl aes-256-cbc -K $encrypted_6014e4216d04_key -iv $encrypted_6014e4216d04_iv -in secring.asc.enc -out /home/travis/build/intel-hadoop/gearpump/secring.asc -d;ls -l /home/travis/build/intel-hadoop/gearpump/secring.asc;fi
-rw-rw-r-- 1 travis travis 1840 Jan 24 23:21 /home/travis/build/intel-hadoop/gearpump/secring.asc
travis_time:end:0da34dd4:start=1422141695104542922,finish=1422141695119096912,duration=14553990
�[0Ktravis_fold:end:before_install.1

however when the signing occurs sbt complains that no secret key is available:

�[0m[�[31merror�[0m] �[0mgpg: no default secret key: secret key not available�[0m

See https://travis-ci.org/intel-hadoop/gearpump/builds/48203130 for full log out.

Compatibility with `sbt-assembly`

So far, this plugin is working great for everything except the Jar files produced by sbt-assembly. Is there a way to configure the plugin to sign those artifacts as well?

For reference, the contents of the SBT configuration file for the sub-project in question is available here.

Thanks!

Disable for `publish-local`

Is it possible to configure the plugin (preferably globally in ~/.sbt) to be bypassed in publish-local. i'm using that a lot in development and i don't want to enter my pass phrase when publishing to my local repository.

gen-key doesn't generate the key pair

Hi,

I'm trying to generate a key pair using sbt-pgp in Play Framework, but the gen-key command doesn't generate the key files. When I introduce the name, email and passphrase, the execution stops, and files are not generated. This is what I get:

[app] $ set pgpReadOnly := false
[info] Defining /:pgpReadOnly
[info] The new value will be used by no settings or tasks.
[info] Reapplying settings...
[info] Set current project to play-bootstrap3 (in build file:/path/to/app/)
[app] $ pgp-cmd gen-key
Please enter the name associated with the key: name
Please enter the email associated with the key: [email protected]
Please enter the passphrase for the key: ******
Please re-enter the passphrase for the key: ******
[info] Creating a new PGP key, this could take a long time.
[app] $

Issue 23, resume unable to sbt publish-local with sbt/xsbt-gpg-plugin v0.5 and v0.6

I have no rights to reopen issue so create new one.

I removed "building from source" and replace it with

addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6")

I tried to publish project again. I got the same error with sbt +publish-local. It it broken anyway :-(
Build system is not significant.
You may try it yourself.

Please enter PGP passphrase:
[info] delivering ivy file to /home/ezh/android/outdated_or_broken/pamflet/app/target/scala-2.9.1/ivy-0.4.2-SNAPSHOT.xml
model contains 23 documentable templates
[info] API documentation generation successful.
[info] Packaging /home/ezh/android/outdated_or_broken/pamflet/library/target/scala-2.9.1/pamflet-library_2.9.1-0.4.2-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
[info] Generating API documentation for main sources...
[info] Compiling 1 Scala source to /home/ezh/android/outdated_or_broken/pamflet/app/target/scala-2.9.1/classes...
[info] Packaging /home/ezh/android/outdated_or_broken/pamflet/library/target/scala-2.9.1/pamflet-library_2.9.1-0.4.2-SNAPSHOT.jar ...
[info] Done packaging.
Please enter PGP passphrase:
[info] Packaging /home/ezh/android/outdated_or_broken/pamflet/app/target/scala-2.9.1/pamflet-app_2.9.1-0.4.2-SNAPSHOT.jar ...
model contains 6 documentable templates
[info] Done packaging.
[info] API documentation generation successful.
[info] Packaging /home/ezh/android/outdated_or_broken/pamflet/app/target/scala-2.9.1/pamflet-app_2.9.1-0.4.2-SNAPSHOT-javadoc.jar ...
[info] Done packaging.
Please enter PGP passphrase:
[error] {file:/home/ezh/android/outdated_or_broken/pamflet/}pamflet/:packaged-artifacts: java.io.IOException: secret key ring doesn't start with secret key tag: tag 0xffffffff
[error] {file:/home/ezh/android/outdated_or_broken/pamflet/}pamflet-app/
:packaged-artifacts: java.io.IOException: secret key ring doesn't start with secret key tag: tag 0xffffffff
[error] {file:/home/ezh/android/outdated_or_broken/pamflet/}pamflet-library/:packaged-artifacts: java.io.IOException: secret key ring doesn't start with secret key tag: tag 0xffffffff
[error] {file:/home/ezh/android/outdated_or_broken/pamflet/}pamflet-knockoff/
:packaged-artifacts: java.io.IOException: secret key ring doesn't start with secret key tag: tag 0xffffffff
[error] Total time: 9 s, completed 13.08.2012 18:04:24

Release for 0.11.0/1

So that we are able at least to release backwards compatible versions of plugins.

NoSuchMethodError : sbt-pgp's BouncyCastle version conflicts with sbt-native-packager's one

It is currently not possible to use both the latest version of sbt-pgp and the latest version(s) of sbt-native-packager in the same project.
This is caused by a conflict in BouncyCastle versions :

  • sbt-pgp uses BouncyCastle 1.49
  • sbt-native-packager 0.7/0.8 uses jdeb, which pulls BouncyCastle 1.51.

Obviously, SBT will pick up the latest version.
Unfortunately, A lot of methods have been removed or deprecated in BouncyCastle 1.51, and sbt-pgp happens to use one of them, which leads to the following stacktrace :

java.lang.NoSuchMethodError: org.bouncycastle.openpgp.PGPSecretKeyRing.<init>(Ljava/io/InputStream;)V
    at com.jsuereth.pgp.SecretKeyRing$.load(SecretKeyRing.scala:55)
    at com.jsuereth.pgp.SecretKeyRing$.load(SecretKeyRing.scala:51)
    at com.jsuereth.pgp.StreamingLoadable$class.loadFromFile(StreamingLoadable.scala:11)
    at com.jsuereth.pgp.SecretKeyRing$.loadFromFile(SecretKeyRing.scala:51)
    at com.jsuereth.pgp.PGP$.loadSecretKeyRing(package.scala:38)
    at com.jsuereth.pgp.cli.PgpStaticContext$class.secretKeyRing(context.scala:31)
    at com.typesafe.sbt.pgp.SbtPgpStaticContext.secretKeyRing(SbtPgpCommandContext.scala:8)
    at com.jsuereth.pgp.cli.DelegatingPgpStaticContext$class.secretKeyRing(context.scala:38)
    at com.typesafe.sbt.pgp.SbtPgpCommandContext.secretKeyRing(SbtPgpCommandContext.scala:13)
    at com.typesafe.sbt.pgp.BouncyCastlePgpSigner$$anonfun$sign$1.apply(PgpSigner.scala:42)
    at com.typesafe.sbt.pgp.BouncyCastlePgpSigner$$anonfun$sign$1.apply(PgpSigner.scala:37)
    at com.typesafe.sbt.pgp.Cache$class.withValue(SbtHelpers.scala:38)
    at com.typesafe.sbt.pgp.PasswordCache$.withValue(SbtHelpers.scala:55)
    at com.typesafe.sbt.pgp.SbtPgpCommandContext$$anonfun$1.apply(SbtPgpCommandContext.scala:34)
    at com.typesafe.sbt.pgp.SbtPgpCommandContext.retry(SbtPgpCommandContext.scala:42)
    at com.typesafe.sbt.pgp.SbtPgpCommandContext.withPassphrase(SbtPgpCommandContext.scala:31)
    at com.typesafe.sbt.pgp.BouncyCastlePgpSigner.sign(PgpSigner.scala:37)
    at com.typesafe.sbt.pgp.PgpSettings$$anonfun$signingSettings$1$$anonfun$apply$1.apply(PgpSettings.scala:120)
    at com.typesafe.sbt.pgp.PgpSettings$$anonfun$signingSettings$1$$anonfun$apply$1.apply(PgpSettings.scala:117)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
    at scala.collection.immutable.Map$Map2.foreach(Map.scala:130)
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:251)
    at scala.collection.AbstractTraversable.flatMap(Traversable.scala:105)
    at com.typesafe.sbt.pgp.PgpSettings$$anonfun$signingSettings$1.apply(PgpSettings.scala:117)
    at com.typesafe.sbt.pgp.PgpSettings$$anonfun$signingSettings$1.apply(PgpSettings.scala:115)
    at scala.Function4$$anonfun$tupled$1.apply(Function4.scala:35)
    at scala.Function4$$anonfun$tupled$1.apply(Function4.scala:34)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
    at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:42)
    at sbt.std.Transform$$anon$4.work(System.scala:64)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
    at sbt.Execute.work(Execute.scala:244)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
    at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
    at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Sidenote : this does not always happens when using both sbt-pgp and sbt-native-packager 0.7/0.8.

The problem arised while I was trying to build an automated release tool for Gatling's various projects, and that required that the pgpPassphrase was set in the build definition instead of manually input during the publication process.

AttributeKey ID collisions

I'm trying to use this plugin for the first time, on a project using scala 2.9.1 and SBT 0.11.2. This error comes up:

[error] AttributeKey ID collisions detected for: 'pgp-signer' (sbt.Task[com.jsuereth.pgp.sbtplugin.PgpSigner], sbt.Task[com.jsuereth.pgp.sbtplugin.PgpSigner], sbt.Task[com.jsuereth.pgp.sbtplugin.PgpSigner], sbt.Task[com.jsuereth.pgp.sbtplugin.PgpSigner]), 'pgp-verifier' (sbt.Task[com.jsuereth.pgp.sbtplugin.PgpVerifier], sbt.Task[com.jsuereth.pgp.sbtplugin.PgpVerifier], sbt.Task[com.jsuereth.pgp.sbtplugin.PgpVerifier], sbt.Task[com.jsuereth.pgp.sbtplugin.PgpVerifier]), 'pgp-context' (sbt.Task[com.jsuereth.pgp.cli.PgpCommandContext], sbt.Task[com.jsuereth.pgp.cli.PgpCommandContext], sbt.Task[com.jsuereth.pgp.cli.PgpCommandContext], sbt.Task[com.jsuereth.pgp.cli.PgpCommandContext]), 'check-pgp-signatures' (sbt.Task[com.jsuereth.pgp.sbtplugin.SignatureCheckReport], sbt.Task[com.jsuereth.pgp.sbtplugin.SignatureCheckReport], sbt.Task[com.jsuereth.pgp.sbtplugin.SignatureCheckReport], sbt.Task[com.jsuereth.pgp.sbtplugin.SignatureCheckReport]), 'pgp-static-context' (com.jsuereth.pgp.cli.PgpStaticContext, com.jsuereth.pgp.cli.PgpStaticContext, com.jsuereth.pgp.cli.PgpStaticContext, com.jsuereth.pgp.cli.PgpStaticContext), 'signatures-module' (sbt.Task[com.jsuereth.pgp.sbtplugin.GetSignaturesModule], sbt.Task[com.jsuereth.pgp.sbtplugin.GetSignaturesModule], sbt.Task[com.jsuereth.pgp.sbtplugin.GetSignaturesModule], sbt.Task[com.jsuereth.pgp.sbtplugin.GetSignaturesModule])

I've created a ~/.sbt/plugins/gpg.sbt file with the following content:

resolvers += Resolver.url("sbt-plugin-releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)

addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6")

sbt-pgp added as dependency to project

I'm working on the gettyimages/spray-swagger#16 project which uses sbt-pgp to publish to sonatype. When spray-swagger is specified as a dependency in another project it requires the user to download sbt-pgp. Sbt-pgp must be then explicitly excluded like so:

libraryDependencies += "com.gettyimages" % "spray-swagger_2.10" % "0.3.2" exclude("com.typesafe.sbt", "sbt-pgp")

For spray-swagger I've specified the sbt-pgp plugin in a ~/.sbt/0.13/sbtpgp.sbt file so I'm not sure why it's being required in the output of spray-swagger. I'm using publish-signed to publish to sonatype.

I'm sure this is just a configuration thing but I'm at a loss how to resolve. I do not to have to explicitly exclude sbt-pgp (or have it be included if only used for publishing).

Thanks,

Mike

java.lang.ClassCastException: Cannot cast com.typesafe.sbt.SbtPgp$ to sbt.Plugin

This is the error I get when I include the plugin in either my ~/.sbt/0.13/plugins/gpg.sbt or in project/plugins.sbt. The line I include it with is this one:

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

The error occurs when I first start up sbt.

Here is the full output:

~/Documents/common > sbt
[info] Loading global plugins from /Users/dirkg/.sbt/0.13/plugins
[info] Updating {file:/Users/dirkg/.sbt/0.13/plugins/}global-plugins...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Loading project definition from /Users/dirkg/Documents/common/project
[info] Updating {file:/Users/dirkg/Documents/common/project/}common-build...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 3 Scala sources to /Users/dirkg/Documents/common/project/target/scala-2.10/sbt-0.13/classes...
java.lang.ClassCastException: Cannot cast com.typesafe.sbt.SbtPgp$ to sbt.Plugin
    at java.lang.Class.cast(Class.java:3258)
    at sbt.ModuleUtilities$.getCheckedObject(ModuleUtilities.scala:20)
    at sbt.ModuleUtilities$$anonfun$getCheckedObjects$1.apply(ModuleUtilities.scala:23)
    at sbt.ModuleUtilities$$anonfun$getCheckedObjects$1.apply(ModuleUtilities.scala:23)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:376)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:376)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1085)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1077)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:376)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:376)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1085)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1077)
    at scala.collection.immutable.Stream$$anonfun$$plus$plus$1.apply(Stream.scala:330)
    at scala.collection.immutable.Stream$$anonfun$$plus$plus$1.apply(Stream.scala:330)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1085)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1077)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:376)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:376)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1085)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1077)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:376)
    at scala.collection.immutable.Stream$$anonfun$map$1.apply(Stream.scala:376)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1085)
    at scala.collection.immutable.Stream$Cons.tail(Stream.scala:1077)
    at scala.collection.immutable.Stream.force(Stream.scala:249)
    at scala.collection.immutable.Stream.mkString(Stream.scala:702)
    at sbt.BuildUtil$.importNames(BuildUtil.scala:83)
    at sbt.BuildUtil$.importAll(BuildUtil.scala:88)
    at sbt.BuildUtil$.importAllRoot(BuildUtil.scala:89)
    at sbt.BuildUtil$.getImports(BuildUtil.scala:80)
    at sbt.DetectedPlugins.imports$lzycompute(BuildStructure.scala:125)
    at sbt.DetectedPlugins.imports(BuildStructure.scala:125)
    at sbt.Load$.sbt$Load$$loadSettingsFile$1(Load.scala:710)
    at sbt.Load$$anonfun$sbt$Load$$memoLoadSettingsFile$1$1.apply(Load.scala:715)
    at sbt.Load$$anonfun$sbt$Load$$memoLoadSettingsFile$1$1.apply(Load.scala:714)
    at scala.Option.getOrElse(Option.scala:120)
    at sbt.Load$.sbt$Load$$memoLoadSettingsFile$1(Load.scala:714)
    at sbt.Load$$anonfun$loadFiles$1$2.apply(Load.scala:721)
    at sbt.Load$$anonfun$loadFiles$1$2.apply(Load.scala:721)
    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.immutable.List.foreach(List.scala:318)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at sbt.Load$.loadFiles$1(Load.scala:721)
    at sbt.Load$.discoverProjects(Load.scala:732)
    at sbt.Load$.discover$1(Load.scala:545)
    at sbt.Load$.discoverAndLoad$1(Load.scala:554)
    at sbt.Load$.loadTransitive(Load.scala:570)
    at sbt.Load$.loadProjects$1(Load.scala:442)
    at sbt.Load$.loadUnit(Load.scala:446)
    at sbt.Load$$anonfun$18$$anonfun$apply$11.apply(Load.scala:281)
    at sbt.Load$$anonfun$18$$anonfun$apply$11.apply(Load.scala:281)
    at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:91)
    at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:90)
    at sbt.BuildLoader.apply(BuildLoader.scala:140)
    at sbt.Load$.loadAll(Load.scala:334)
    at sbt.Load$.loadURI(Load.scala:289)
    at sbt.Load$.load(Load.scala:285)
    at sbt.Load$.load(Load.scala:276)
    at sbt.Load$.apply(Load.scala:130)
    at sbt.Load$.defaultLoad(Load.scala:36)
    at sbt.BuiltinCommands$.doLoadProject(Main.scala:481)
    at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:475)
    at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:475)
    at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:58)
    at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:58)
    at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:60)
    at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:60)
    at sbt.Command$.process(Command.scala:92)
    at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:98)
    at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:98)
    at sbt.State$$anon$1.process(State.scala:184)
    at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:98)
    at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:98)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
    at sbt.MainLoop$.next(MainLoop.scala:98)
    at sbt.MainLoop$.run(MainLoop.scala:91)
    at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:70)
    at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:65)
    at sbt.Using.apply(Using.scala:24)
    at sbt.MainLoop$.runWithNewLog(MainLoop.scala:65)
    at sbt.MainLoop$.runAndClearLast(MainLoop.scala:48)
    at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:32)
    at sbt.MainLoop$.runLogged(MainLoop.scala:24)
    at sbt.StandardMain$.runManaged(Main.scala:53)
    at sbt.xMain.run(Main.scala:28)
    at xsbt.boot.Launch$$anonfun$run$1.apply(Launch.scala:109)
    at xsbt.boot.Launch$.withContextLoader(Launch.scala:129)
    at xsbt.boot.Launch$.run(Launch.scala:109)
    at xsbt.boot.Launch$$anonfun$apply$1.apply(Launch.scala:36)
    at xsbt.boot.Launch$.launch(Launch.scala:117)
    at xsbt.boot.Launch$.apply(Launch.scala:19)
    at xsbt.boot.Boot$.runImpl(Boot.scala:44)
    at xsbt.boot.Boot$.main(Boot.scala:20)
    at xsbt.boot.Boot.main(Boot.scala)
[error] java.lang.ClassCastException: Cannot cast com.typesafe.sbt.SbtPgp$ to sbt.Plugin
[error] Use 'last' for the full log.

Allow empty passphrase

When a publish command prompts "Please enter PGP passphrase" and no passphrase is entered, the command immediately halts with the message "Empty passphrase. aborting..."

Is there a good reason for this? As far as I know, it's legitimate to have a PGP key with an empty passphrase. I've had no trouble using this same passphraseless key with maven-gpg-plugin.

Select used gpg key

I failed selecting a desired key for signing using pgpSigningKey or usePgpKeyHex. I always end up with [error] (.../*:signedArtifacts) Could not find public key: .... None of the numeric or hex key ids listed for my secret key in gpg --list-keys or gpg --list-keys --with-colon seem to work.

@jsuereth suggested some fuzzy matching on the key id may fix that, hence the ticket.

Exclude project from being published

I can't find any information on how to exclude a particular sub project in a multi project from being published via publish-signed.

If I have an aggregate root and two aggregates sub projects foo and bar, how do I make sbt-pgp skip root and not publish that? It would also be useful to add that information to the documentation website. Thanks.

unable to sbt publish-local with sbt/xsbt-gpg-plugin v0.5 and v0.6

How to reproduce:

git clone [email protected]:ezh/pamflet.git
edit project/project/Build.scala
change lazy val gpg = uri("git://github.com/sbt/xsbt-gpg-plugin.git#0.4") to 0.5 or 0.6
sbt publish-local

press enter for all Please enter your PGP passphrase>

Output

0.4 working as expected without any issues

gpg: no default secret key: No secret key
gpg: signing failed: No secret key
gpg: no default secret key: No secret key
gpg: signing failed: No secret key
gpg: no default secret key: No secret key
gpg: signing failed: No secret key
[info] delivering ivy file to /home/ezh/android/outdated_or_broken/pamflet/library/target/scala-2.9.1/ivy-0.4.2-SNAPSHOT.xml
gpg: no default secret key: No secret key
gpg: signing failed: No secret key
[info] :: delivering :: net.databinder#pamflet-app_2.9.1;0.4.2-SNAPSHOT :: 0.4.2-SNAPSHOT :: release :: Mon Aug 13 12:22:11 MSK 2012
[info] delivering ivy file to /home/ezh/android/outdated_or_broken/pamflet/app/target/scala-2.9.1/ivy-0.4.2-SNAPSHOT.xml
[info] published pamflet-library_2.9.1 to /home/ezh/.ivy2/local/net.databinder/pamflet-library_2.9.1/0.4.2-SNAPSHOT/jars/pamflet-library_2.9.1.jar
[info] published pamflet-library_2.9.1 to /home/ezh/.ivy2/local/net.databinder/pamflet-library_2.9.1/0.4.2-SNAPSHOT/docs/pamflet-library_2.9.1-javadoc.jar
[info] published pamflet-library_2.9.1 to /home/ezh/.ivy2/local/net.databinder/pamflet-library_2.9.1/0.4.2-SNAPSHOT/poms/pamflet-library_2.9.1.pom
[info] published pamflet-library_2.9.1 to /home/ezh/.ivy2/local/net.databinder/pamflet-library_2.9.1/0.4.2-SNAPSHOT/srcs/pamflet-library_2.9.1-sources.jar
[info] published ivy to /home/ezh/.ivy2/local/net.databinder/pamflet-library_2.9.1/0.4.2-SNAPSHOT/ivys/ivy.xml
[info] published pamflet-app_2.9.1 to /home/ezh/.ivy2/local/net.databinder/pamflet-app_2.9.1/0.4.2-SNAPSHOT/srcs/pamflet-app_2.9.1-sources.jar
[info] published pamflet-app_2.9.1 to /home/ezh/.ivy2/local/net.databinder/pamflet-app_2.9.1/0.4.2-SNAPSHOT/jars/pamflet-app_2.9.1.jar
[info] published pamflet-app_2.9.1 to /home/ezh/.ivy2/local/net.databinder/pamflet-app_2.9.1/0.4.2-SNAPSHOT/poms/pamflet-app_2.9.1.pom
[info] published pamflet-app_2.9.1 to /home/ezh/.ivy2/local/net.databinder/pamflet-app_2.9.1/0.4.2-SNAPSHOT/docs/pamflet-app_2.9.1-javadoc.jar
[info] published ivy to /home/ezh/.ivy2/local/net.databinder/pamflet-app_2.9.1/0.4.2-SNAPSHOT/ivys/ivy.xml
[success] Total time: 0 s, completed 13.08.2012 12:22:11

0.5 - publishing broken

[info] Set current project to pamflet (in build file:/home/ezh/android/outdated_or_broken/pamflet/)
Please enter your PGP passphrase>
[warn] Credentials file /home/ezh/.ivy2/.credentials does not exist
[warn] Credentials file /home/ezh/.ivy2/.credentials does not exist
Please enter your PGP passphrase>
Please enter your PGP passphrase>
Please enter your PGP passphrase>
[warn] Credentials file /home/ezh/.ivy2/.credentials does not exist
[info] :: delivering :: net.databinder#pamflet_2.9.1;0.4.2-SNAPSHOT :: 0.4.2-SNAPSHOT :: release :: Mon Aug 13 12:20:23 MSK 2012
[info] delivering ivy file to /home/ezh/android/outdated_or_broken/pamflet/target/scala-2.9.1/ivy-0.4.2-SNAPSHOT.xml
[info] Wrote /home/ezh/android/outdated_or_broken/pamflet/knockoff/target/scala-2.9.1/pamflet-knockoff_2.9.1-0.4.2-SNAPSHOT.pom
[info] Wrote /home/ezh/android/outdated_or_broken/pamflet/target/scala-2.9.1/pamflet_2.9.1-0.4.2-SNAPSHOT.pom
[info] :: delivering :: net.databinder#pamflet-library_2.9.1;0.4.2-SNAPSHOT :: 0.4.2-SNAPSHOT :: release :: Mon Aug 13 12:20:25 MSK 2012
[info] delivering ivy file to /home/ezh/android/outdated_or_broken/pamflet/library/target/scala-2.9.1/ivy-0.4.2-SNAPSHOT.xml
[info] Wrote /home/ezh/android/outdated_or_broken/pamflet/library/target/scala-2.9.1/pamflet-library_2.9.1-0.4.2-SNAPSHOT.pom
[info] :: delivering :: net.databinder#pamflet-knockoff_2.9.1;0.4.2-SNAPSHOT :: 0.4.2-SNAPSHOT :: release :: Mon Aug 13 12:20:25 MSK 2012
[info] delivering ivy file to /home/ezh/android/outdated_or_broken/pamflet/knockoff/target/scala-2.9.1/ivy-0.4.2-SNAPSHOT.xml
[warn] Credentials file /home/ezh/.ivy2/.credentials does not exist
[info] Wrote /home/ezh/android/outdated_or_broken/pamflet/app/target/scala-2.9.1/pamflet-app_2.9.1-0.4.2-SNAPSHOT.pom
[info] :: delivering :: net.databinder#pamflet-app_2.9.1;0.4.2-SNAPSHOT :: 0.4.2-SNAPSHOT :: release :: Mon Aug 13 12:20:25 MSK 2012
[info] delivering ivy file to /home/ezh/android/outdated_or_broken/pamflet/app/target/scala-2.9.1/ivy-0.4.2-SNAPSHOT.xml
[error] {file:/home/ezh/android/outdated_or_broken/pamflet/}pamflet/:packaged-artifacts: java.io.IOException: secret key ring doesn't start with secret key tag: tag 0xffffffff
[error] {file:/home/ezh/android/outdated_or_broken/pamflet/}pamflet-app/
:packaged-artifacts: java.io.IOException: secret key ring doesn't start with secret key tag: tag 0xffffffff
[error] {file:/home/ezh/android/outdated_or_broken/pamflet/}pamflet-library/:packaged-artifacts: java.io.IOException: secret key ring doesn't start with secret key tag: tag 0xffffffff
[error] {file:/home/ezh/android/outdated_or_broken/pamflet/}pamflet-knockoff/
:packaged-artifacts: java.io.IOException: secret key ring doesn't start with secret key tag: tag 0xffffffff
[error] Total time: 3 s, completed 13.08.2012 12:20:25

0.6 - unable to build

[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.jsuereth#xsbt-gpg-plugin;0.5: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.
[warn] com.jsuereth:xsbt-gpg-plugin:0.5 (sbtVersion=0.11.3, scalaVersion=2.9.1)
[warn]
[error] {file:/home/ezh/.sbt/staging/a9d1d8d001c249be95f0/project/}plugins/*:update: sbt.ResolveException: unresolved dependency: com.jsuereth#xsbt-gpg-plugin;0.5: not found
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?

1.0.0: ExceptionInInitializerError when using predefined passphrase

When using

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

with

val x = System.getProperty("PGP_PASSPHRASE").toCharArray

pgpPassphrase := Some(x)

and calling

PGP_PASSPHRASE=asdfgh sbt publish-local-signed

I am getting the following exception:

java.lang.ExceptionInInitializerError
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:270)
    at sbt.compiler.Eval$.getModule(Eval.scala:427)
    at sbt.compiler.EvalDefinitions.values(Eval.scala:36)
    at sbt.EvaluateConfigurations$$anonfun$7.apply(EvaluateConfigurations.scala:101)
    at sbt.EvaluateConfigurations$$anonfun$7.apply(EvaluateConfigurations.scala:101)
    at sbt.EvaluateConfigurations$$anonfun$evaluateSbtFile$1.apply(EvaluateConfigurations.scala:110)
    at sbt.EvaluateConfigurations$$anonfun$evaluateSbtFile$1.apply(EvaluateConfigurations.scala:110)
    at sbt.Load$.sbt$Load$$loadSettingsFile$1(Load.scala:507)
    at sbt.Load$$anonfun$sbt$Load$$memoLoadSettingsFile$1$1.apply(Load.scala:502)
    at sbt.Load$$anonfun$sbt$Load$$memoLoadSettingsFile$1$1.apply(Load.scala:501)
    at scala.Option.getOrElse(Option.scala:120)
    at sbt.Load$.sbt$Load$$memoLoadSettingsFile$1(Load.scala:501)
    at sbt.Load$$anonfun$loadSettings$1$2.apply(Load.scala:500)
    at sbt.Load$$anonfun$loadSettings$1$2.apply(Load.scala:500)
    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.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.AbstractTraversable.map(Traversable.scala:105)
    at sbt.Load$.loadSettings$1(Load.scala:500)
    at sbt.Load$.sbt$Load$$expand$1(Load.scala:523)
    at sbt.Load$.loadSettings(Load.scala:528)
    at sbt.Load$.sbt$Load$$loadSbtFiles$1(Load.scala:464)
    at sbt.Load$.defaultLoad$1(Load.scala:475)
    at sbt.Load$.loadTransitive(Load.scala:478)
    at sbt.Load$.loadProjects$1(Load.scala:418)
    at sbt.Load$.loadUnit(Load.scala:419)
    at sbt.Load$$anonfun$15$$anonfun$apply$11.apply(Load.scala:256)
    at sbt.Load$$anonfun$15$$anonfun$apply$11.apply(Load.scala:256)
    at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:93)
    at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:92)
    at sbt.BuildLoader.apply(BuildLoader.scala:143)
    at sbt.Load$.loadAll(Load.scala:312)
    at sbt.Load$.loadURI(Load.scala:264)
    at sbt.Load$.load(Load.scala:260)
    at sbt.Load$.load(Load.scala:251)
    at sbt.Load$.apply(Load.scala:134)
    at sbt.Load$.defaultLoad(Load.scala:37)
    at sbt.BuiltinCommands$.doLoadProject(Main.scala:473)
    at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:467)
    at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:467)
    at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:60)
    at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:60)
    at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:62)
    at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:62)
    at sbt.Command$.process(Command.scala:95)
    at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:100)
    at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:100)
    at sbt.State$$anon$1.process(State.scala:179)
    at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:100)
    at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:100)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
    at sbt.MainLoop$.next(MainLoop.scala:100)
    at sbt.MainLoop$.run(MainLoop.scala:93)
    at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:71)
    at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:66)
    at sbt.Using.apply(Using.scala:25)
    at sbt.MainLoop$.runWithNewLog(MainLoop.scala:66)
    at sbt.MainLoop$.runAndClearLast(MainLoop.scala:49)
    at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:33)
    at sbt.MainLoop$.runLogged(MainLoop.scala:25)
    at sbt.StandardMain$.runManaged(Main.scala:57)
    at sbt.xMain.run(Main.scala:29)
    at xsbt.boot.Launch$$anonfun$run$1.apply(Launch.scala:109)
    at xsbt.boot.Launch$.withContextLoader(Launch.scala:128)
    at xsbt.boot.Launch$.run(Launch.scala:109)
    at xsbt.boot.Launch$$anonfun$apply$1.apply(Launch.scala:35)
    at xsbt.boot.Launch$.launch(Launch.scala:117)
    at xsbt.boot.Launch$.apply(Launch.scala:18)
    at xsbt.boot.Boot$.runImpl(Boot.scala:41)
    at xsbt.boot.Boot$.main(Boot.scala:17)
    at xsbt.boot.Boot.main(Boot.scala)

Can't run gen-key

After adding sbt-gpg 0.8.3 I try to generate a key for a project and am encountering a failure to run pgp-cmd: GeneratePgpKey():

> pgp-cmd gen-key
[error] Cannot modify keyrings when in read-only mode.  Run `set pgpReadOnly := false` before running this command.
[error] Use 'last' for the full log.
> set pgpReadOnly := false
[info] Defining */*:pgpReadOnly
[info] The new value will be used by no settings or tasks.
[info] Reapplying settings...
[info] Set current project to stockman (in build file:/Users/mhamrah/dev/p/stockman/)
> pgp-cmd gen-key
Failed to run pgp-cmd: GeneratePgpKey().   Please report this issue at http://github.com/sbt/sbt-pgp/issues
>

Any ideas? Also fails when useGpg := true

Thanks

Passphrase and Umlauts

Environment: OS X 10.6 with GPGTools.

It seems that when there are Umlauts in the passphrase (in my case German letter 'ä') that the phrase is not correctly recognized by the plugin. I re-typed the phrase with characters visible in GPG Keychain Access, so I'm sure there wasn't any typo.

The sbt plugin or rather bouncy castle emit a strange error message: "org.bouncycastle.openpgp.PGPException: checksum mismatch at 0 of 20" (if you google for it, you see it's a bounce castle thing: http://bouncy-castle.1462172.n4.nabble.com/Getting-quot-checksum-mismatch-at-0-of-20-quot-when-trying-to-extractPrivateKey-td1467919.html)

After I changed 'ä' for 'ae', it works, so unless I was really typing it wrong repeatedly, the reason seems to be character encoding.

Failed to run pgp-cmd: GeneratePgpKey()

Sbt version: 0.13.5
sbt-pgp version: 0.8.3

Steps to reproduce:

  • Added addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") to project/plugins.sbt.
  • Started sbt prompt in the root of the project
  • Ran the pgp-cmd gen-key command
  • Got "Cannot modify keyrings when in read-only mode. Run set pgpReadOnly := false before running this command."
  • Ran set pgpReadOnly := false
  • Ran pgp-cmd gen-key
  • Got "Failed to run pgp-cmd: GeneratePgpKey(). Please report this issue at http://github.com/sbt/sbt-pgp/issues"

gen-key does nothing

Config

    $ cat ~/.sbt/0.13/plugins/gpg.sbt 
    addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.1")

Session

    $ sbt
    Loading /home/jem/tools/sbt-0.13.1/bin/sbt-launch-lib.bash
    [info] Loading global plugins from /home/jem/.sbt/0.13/plugins
    [info] Set current project to jem (in build file:/home/jem/projects/blogs/jem/)
    > set pgpReadOnly := false
    [info] Defining */*:pgpReadOnly
    [info] The new value will be used by no settings or tasks.
    [info] Reapplying settings...
    [info] Set current project to jem (in build file:/home/jem/projects/blogs/jem/)
    > pgp-cmd gen-key
    > pgp-cmd list-keys
    /home/jem/.gnupg/pubring.gpg
    ----------------------------

    > exit

How can I debug this further?

Latest sbt-pgp breaks community build

The breakage looks like:

[sbt-pgp:error] /localhome/jenkinsdbuild3/workspace/Community-2.11.x/target-0.9.1/extraction/339159ea2e9fa8b3beb4289cbd915661e0b05139/projects/19c0b8b27033f64bd4818d752178a911efec4e19/build.sbt:0: error: '.' expected but eof found.
[sbt-pgp:error] import _root_.sbt.plugins.IvyPlugin, _root_.sbt.plugins.JvmPlugin, _root_.sbt.plugins.CorePlugin, _root_.sbt.plugins.JUnitXmlReportPlugin, PgpCommonSettings
[sbt-pgp:error]                                                                                                                                                             ^
[sbt-pgp] sbt.compiler.EvalException: Error parsing imports for expression.

See scala/community-build#60 for more details.

Doesn't read a passphrase from keyboard

I use version :

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

and

vkostyukov@corvus:finch$ gpg --version
gpg (GnuPG) 1.4.18

When I do publishSigned plugin asks me for passphrase and then prints:

Enter passphrase: [error] gpg: Invalid passphrase; please try again ...

I'm pretty sure I know my passphrase (and I regenerated it like 10 times today). It seems that the plugin doesn't read the input from keyboard. I also tried to specify the passphrase in ~/.sbt/gpg.sbt in pgpPassphrase variable but it's still asking me for a passphrase in the console, which is weird.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.