diff --git a/.travis.yml b/.travis.yml index b964f3c..aa17538 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,13 @@ language: scala env: global: - - PUBLISH_JDK=oraclejdk8 # admin/build.sh only publishes when running on this jdk -# Don't commit sensitive files, instead commit a version encrypted with $SECRET, -# this environment variable is encrypted with this repo's private key and stored below: -# (See http://docs.travis-ci.com/user/environment-variables/#Secure-Variables.) - secure: "sGB53QddmPmQ4ftCGYxT0gaJcFt0bpMJoGxJRJCFTxdzg6nNMqJ9qDWbyJo7vDFx30axNQlyBH928pUiS5KfsmvzVdoVHUBEUJlF1lBurlpx06tGLuBdcFDwUF5ybi7SGRNdUPuX/6uLdgK5clpcW16/pcfT5Qr5vo/0mvPY85s=" + - PUBLISH_JDK=oraclejdk8 + # PGP_PASSPHRASE + - secure: "BzgzRZLYa52rS/hBfzf43b++CfDhdcd3Mmu8tsyBHgThSQOd2YBLbV5kWD8aYVFKVHfW7XX0PTe3F+rR/fFZqGItE6o8Px0Y7Vzb5pqjlaQdxFEJ+WrsnshS0xuAKZ7OwVHRp+d+jznaCwRxEo2vpW3ko1OPAJ8cxfhVL/4C1I0=" + # SONA_USER + - secure: "lx2qFeFxh9AFmyHR7hH4Qf9flIEx8VgYj6ebzuxp1cc1ZZiXHC1256x0bHFDUH9bhJACOazOrco/+v6MBAriBkWxLBc98FrC6OkVeQMFW2ffWSBuHRclilKsQA/Lsgc81Wg+WV105hOqUNAkTXgroblInNt+KS+DhC/8FVoh9ZY=" + # SONA_PASS + - secure: "FZC+FZnBNeklA150vW5QDZJ5J7t+DExJrgyXWM46Wh0MobjH8cvydgC3qatItb0rDBV8l7zO1LDwl2KEi92aefw2a8E49z6qVOHgUXiI3SAx7M0UO0FFeKPmTXCLcBlbnGLcUqNjIZfuIEufQvPblKTl8qN4eMmcMn9jsNzJr28=" script: - admin/build.sh scala: diff --git a/admin/README.md b/admin/README.md new file mode 100644 index 0000000..addabae --- /dev/null +++ b/admin/README.md @@ -0,0 +1,58 @@ +## Tag Driven Releasing + +### Background Reading + + - http://docs.travis-ci.com/user/environment-variables/ + - http://docs.travis-ci.com/user/encryption-keys/ + - http://docs.travis-ci.com/user/encrypting-files/ + +### Initial setup for the repository + +To configure tag driven releases from Travis CI. + + 1. Generate a key pair for this repository with `./admin/genKeyPair.sh`. + Edit `.travis.yml` and `admin/build.sh` as prompted. + 2. Publish the public key to https://pgp.mit.edu + 3. Store other secrets as encrypted environment variables with `admin/encryptEnvVars.sh`. + Edit `.travis.yml` as prompted. + 4. Edit `.travis.yml` to use `./admin/build.sh` as the build script, + and edit that script to use the tasks required for this project. + 5. Edit `.travis.yml` to select which JDK will be used for publishing. + +It is important to add comments in .travis.yml to identify the name +of each environment variable encoded in a `:secure` section. + +After all of these steps, your .travis.yml should contain config of the +form: + + language: scala + env: + global: + - PUBLISH_JDK=openjdk6 + # PGP_PASSPHRASE + - secure: "XXXXXX" + # SONA_USER + - secure: "XXXXXX" + # SONA_PASS + - secure: "XXXXXX" + script: + - admin/build.sh + +If Sonatype credentials change in the future, step 3 can be repeated +without generating a new key. + +### Testing + + 1. Follow the release process below to create a dummy release (e.g. 0.1.0-TEST1). + Confirm that the release was staged to Sonatype but do not release it to Maven + central. Instead, drop the staging repository. + +### Performing a release + + 1. Create a GitHub "Release" (with a corresponding tag) via the GitHub + web interface. + 2. Travis CI will schedule a build for this release. Review the build logs. + 3. Log into https://oss.sonatype.org/ and identify the staging repository. + 4. Sanity check its contents + 5. Release staging repository to Maven and send out release announcement. + diff --git a/admin/build.sh b/admin/build.sh index d9e2bce..2ce0f4b 100755 --- a/admin/build.sh +++ b/admin/build.sh @@ -10,10 +10,14 @@ if [ "$TRAVIS_JDK_VERSION" == "$PUBLISH_JDK" ] && [[ "$TRAVIS_TAG" =~ ^v[0-9]+\. myVer=$(echo $TRAVIS_TAG | sed -e s/^v// | sed -e 's/_[0-9]*\.[0-9]*//') publishVersion='set every version := "'$myVer'"' extraTarget="publish-signed" - cat admin/gpg.sbt >> project/plugins.sbt - admin/decrypt.sh sensitive.sbt - (cd admin/ && ./decrypt.sh secring.asc) + cp admin/publish-settings.sbt . + + # Copied from the output of genKeyPair.sh + K=$encrypted_1ce132863fa7_key + IV=$encrypted_1ce132863fa7_iv + + aes-256-cbc -K $K -iv $IV -in admin/secring.asc.enc -out admin/secring.asc -d fi sbt ++$TRAVIS_SCALA_VERSION "$publishVersion" clean update test publishLocal $extraTarget diff --git a/admin/decrypt.sh b/admin/decrypt.sh deleted file mode 100755 index 3c3c602..0000000 --- a/admin/decrypt.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -openssl aes-256-cbc -pass "pass:$SECRET" -in $1.enc -out $1 -d -a \ No newline at end of file diff --git a/admin/encrypt.sh b/admin/encrypt.sh deleted file mode 100755 index 4bf6c93..0000000 --- a/admin/encrypt.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -openssl aes-256-cbc -pass "pass:$SECRET" -in $1 -out $1.enc -a \ No newline at end of file diff --git a/admin/encryptAll.sh b/admin/encryptAll.sh deleted file mode 100755 index de7016b..0000000 --- a/admin/encryptAll.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -# Based on https://gist.github.com/kzap/5819745: - -echo "This will encrypt the cleartext sensitive.sbt and admin/secring.asc, while making the encrypted versions available for decryption on Travis." -echo "Update your .travis.yml as directed, and delete the cleartext versions." -echo "Press enter to continue." -read - -# 1. create a secret, put it in an environment variable while encrypting files -- UNSET IT AFTER -export SECRET=$(cat /dev/urandom | head -c 10000 | openssl sha1) - -# 2. add the "secure: ..." line under the env section -- generate it with `` (install the travis gem first) -travis encrypt SECRET=$SECRET - -admin/encrypt.sh admin/secring.asc -admin/encrypt.sh sensitive.sbt - -echo "Remember to rm sensitive.sbt admin/secring.asc -- once you do, they cannot be recovered (except on Travis)!" \ No newline at end of file diff --git a/admin/encryptEnvVars.sh b/admin/encryptEnvVars.sh new file mode 100755 index 0000000..b625667 --- /dev/null +++ b/admin/encryptEnvVars.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# +# Encrypt sonatype credentials so that they can be +# decrypted in trusted builds on Travis CI. +# +set -e + +read -s -p 'SONA_USER: ' SONA_USER +travis encrypt SONA_USER="$SONA_USER" +read -s -p 'SONA_PASS: ' SONA_PASS +travis encrypt SONA_PASS="$SONA_PASS" diff --git a/admin/genKeyPair.sh b/admin/genKeyPair.sh new file mode 100755 index 0000000..11f7a1e --- /dev/null +++ b/admin/genKeyPair.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# +# Generates a key pair for this repository to sign artifacts. +# Encrypt the private key and its passphrase in trusted builds +# on Travis CI. +# +set -e + +# Based on https://gist.github.com/kzap/5819745: +function promptDelete() { + if [[ -f "$1" ]]; then + echo About to delete $1, Enter for okay / CTRL-C to cancel + read + rm "$1" + fi +} +for f in admin/secring.asc.enc admin/secring.asc admin/pubring.asc; do promptDelete "$f"; done + +echo Generating key pair. Please enter 1. repo name 2. scala-internals@googlegroups.com, 3. a new passphrase +cp admin/gpg.sbt project +sbt 'set pgpReadOnly := false' \ + 'set pgpPublicRing := file("admin/pubring.asc")' \ + 'set pgpSecretRing := file("admin/secring.asc")' \ + 'pgp-cmd gen-key' +rm project/gpg.sbt + +echo ============================================================================================ +echo Encrypting admin/secring.asc. Update K and IV variables in admin/build.sh accordingly. +echo ============================================================================================ +travis encrypt-file admin/secring.asc +rm admin/secring.asc +mv secring.asc.enc admin + +echo ============================================================================================ +echo Encrypting environment variables. Add each to a line in .travis.yml. Include a comment +echo with the name of the corresponding variable +echo ============================================================================================ +read -s -p 'PGP_PASSPHRASE: ' PGP_PASSPHRASE +travis encrypt PGP_PASSPHRASE="$PGP_PASSPHRASE" + diff --git a/admin/gpg.sbt b/admin/gpg.sbt index 01157e6..d60e366 100644 --- a/admin/gpg.sbt +++ b/admin/gpg.sbt @@ -1,26 +1,2 @@ addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") // only added when publishing: - -// There's a companion sensitive.sbt, which was created like this: -// -// 1. in an sbt shell that has the sbt-pgp plugin, create pgp key in admin/: -// -// sbt -// set pgpReadOnly := false -// set pgpPublicRing := file("admin/pubring.asc") -// set pgpSecretRing := file("admin/secring.asc") -// pgp-cmd gen-key // use $passPhrase -// Please enter the name associated with the key: $repoName -// Please enter the email associated with the key: scala-internals@googlegroups.com -// Please enter the passphrase for the key: $passphrase -// -// 2. create sensitive.sbt with contents: -// -// pgpPassphrase := Some($passPhrase.toArray) -// -// pgpPublicRing := file("admin/pubring.asc") -// -// pgpSecretRing := file("admin/secring.asc") -// -// credentials += Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", $sonaUser, $sonaPass) - diff --git a/admin/publish-settings.sbt b/admin/publish-settings.sbt new file mode 100644 index 0000000..21aa4f2 --- /dev/null +++ b/admin/publish-settings.sbt @@ -0,0 +1,7 @@ +pgpPassphrase := Some(sys.prop("PGP_PASSPHRASE").toArray) + +pgpPublicRing := file("admin/pubring.asc") + +pgpSecretRing := file("admin/secring.asc") + +credentials += Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", sys.prop("SONA_USER"), sys.prop("SONA_PASS")) diff --git a/admin/pubring.asc b/admin/pubring.asc index 4b56eca..5d5dd87 100644 --- a/admin/pubring.asc +++ b/admin/pubring.asc @@ -1,18 +1,18 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: BCPG v1.49 -mQENBFSzVhYBCADp261YcgfWCNZ/IrSpvk1LaqnomeDjktUuCy3LD0WQ/B750vpV -gograxIWDfGK3TaHHdiRTV0OmfhhA6Dv/E8wFiHc1psn8mtaL+tQQcFHCLqBnTEe -/VQXZLrHoFsMSBRrFY0rHZGXtCS0DKIxSeqlba4RH9eS4Q35LzBjMBLKewBCwben -mDMOMxLgTS21xqe7OoyrcQGg3nFPLBMM8hgrqmVH9lYc5c2NuTMSHC4/wUozTwMm -SxmEQ1Ga2lEpVAcaJ6r7bz0+QwX62cMs57nkGuf3SP2D5/+igDkkoVb447wESHHG -s3BZw9ThblHXJOZ5Xb64fvQ3/vCjivLqZIepABEBAAG0NXNjYWxhLWphdmE4LWNv +mQENBFS1xA0BCAC0t2c5MhkWyUbkWsZM4DmIN+/pDjNCr2DNmbIG3gB8i4MI71q/ +fj+Ob0lemjJNnNc4ii6+s9RrOcwR1EU4IA8mO79NN+i2yVUhe0LmOWgyfXvG8Qpg +hLmdMrkgOHK0hpWbXJ0i2NGPch4gI6YRJF95yLojz2KENmiYGmSD8p1It06O2824 +Xhqc5Cm72/qXvonHP1+MugjiPxmyZN3ajSol0P7tZlgB7ikqpyL3kZXkc162bJ+H +U6y6qUCcQqS5VQ7Fv9bIbTNOjN4ELLJn2ffLVe3ujRG6seioL0MfuQ/gV9IpGcGO +Dew8Xu79QdDyVHQKgDy9N/J276JZ4j9nYCCxABEBAAG0NXNjYWxhLWphdmE4LWNv bXBhdCA8c2NhbGEtaW50ZXJuYWxzQGdvb2dsZWdyb3Vwcy5jb20+iQEcBBMBAgAG -BQJUs1YWAAoJEF7zF/88US8Xdw4IAJmPcOka4Tc5s5eYAdwZuNOqUiuNO3/9+Za6 -tdGZQfQxUVN5PdgXhAGiKfRxrtSTjfzN+O/wiF/7NDqOQXBHNEx53Rzucq770WvL -G5hUwr8MJB577OIyU2CQquslva3h2LbOt8lEHplLy0tI00zm6ueJNmxq36C4Mu3h -l6QMs0zd29OqtUjWpkUNRnz+1HSdhRCPZNhX1bjhRaJARrhUtP24+g3wKgjg3H95 -yjPh4951r21w/x7msu+w0vSpdA7j/VJIzql6+2exh14YeLx9AFVDgvkJE6McHXX3 -ccr1eQ0FjYpWWUrBMXpS1Pz4SiwXEOOhs1xtsM7fHuikqhkXfHg= -=oZnQ +BQJUtcQNAAoJEGQWNEmlKase8pAH/Rb45Px88u7DDT53DU68zh84oDZLv9i46g7g +16KI97nz17F9OEHdkzNEUA3EgCD1d2k+c/GIdQKg3avVdpNM7krK5SSNgHKcwe/F +0YGMxvh+LgeK1JDuXFbwLJKR+7VIGVKkjw+Z2TC8hZfnD6Qy6c4xkukoBs6yfWQO +tf8gSH6oQox4UIOB/+ADyypl9mnRxgdi1uPvd6UJnL/n9UDE8v1k+8WzO34nTVZr +xWN28pAun5VpLuEq4GAr2JRfRiF+N0hGuS+htiU6hnO81BBK+NusWxI9Aitu8Zyh +eulWpROXvUOw1eJequutgyGwEEQkRi+Yu+2eSM2/EPCWiLXkODk= +=Qro7 -----END PGP PUBLIC KEY BLOCK----- diff --git a/admin/secring.asc.enc b/admin/secring.asc.enc index 1d7d32b..bc600f9 100644 Binary files a/admin/secring.asc.enc and b/admin/secring.asc.enc differ diff --git a/sensitive.sbt.enc b/sensitive.sbt.enc deleted file mode 100644 index 90b6271..0000000 --- a/sensitive.sbt.enc +++ /dev/null @@ -1,7 +0,0 @@ -U2FsdGVkX18PW91o6/n5xLjlSIP+q3wKS3jHVWD5fbGyq6eu9milKZ3bl6i3YmQX -t6NiVtuFuJjix9pqlNgSc4SNInGnvI0kfyYTtcp0/CdZsKsmfUL5lRYxyOo2NIM5 -z/yXD7C9eU1ul48CXNgVOAC2F4w25bdI0iQzvUPRYG5gkiofdP7KL6n0yOlGnSJN -M0KhTrqCLcqVG4cRBZ9Q3+Rip8Lr/F00NSBUcSyL06kag/Zd/iCf3xm76eX/WN59 -Wofi5p+nvPqYSCJc+e/8Dx+aiyj0m2aeXYzwiYDdUQlBGUk8f2+CPy1NlEPGMuET -6p2zc60YT/ohUp1YUGxbvIlZ7S1FzMmiJvpT1VcnouIAYAOVGHqW0ClbPmmXiTkW -W/cGjYYDKiZNQ+8qXhfrF7rxJYiJ8LPMioh5mnzlBSk=