diff options
Diffstat (limited to 'admin')
-rw-r--r-- | admin/README.md | 72 | ||||
-rwxr-xr-x | admin/build.sh | 56 | ||||
-rwxr-xr-x | admin/decrypt.sh | 2 | ||||
-rwxr-xr-x | admin/encrypt.sh | 2 | ||||
-rwxr-xr-x | admin/encryptAll.sh | 19 | ||||
-rwxr-xr-x | admin/encryptEnvVars.sh | 11 | ||||
-rwxr-xr-x | admin/genKeyPair.sh | 41 | ||||
-rw-r--r-- | admin/gpg.sbt | 26 | ||||
-rw-r--r-- | admin/publish-settings.sbt | 9 | ||||
-rw-r--r-- | admin/pubring.asc | 28 | ||||
-rw-r--r-- | admin/secring.asc.enc | bin | 2535 -> 1856 bytes |
11 files changed, 193 insertions, 73 deletions
diff --git a/admin/README.md b/admin/README.md new file mode 100644 index 0000000..46626b4 --- /dev/null +++ b/admin/README.md @@ -0,0 +1,72 @@ +## 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. + 1. Publish the public key to https://pgp.mit.edu + 1. Store other secrets as encrypted environment variables with `admin/encryptEnvVars.sh`. + Edit `.travis.yml` as prompted. + 1. Edit `.travis.yml` to use `./admin/build.sh` as the build script, + and edit that script to use the tasks required for this project. + 1. Edit `build.sbt`'s `scalaVersionsByJvm in ThisBuild` to select Scala and JVM version + combinations that 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 these steps, your `.travis.yml` should contain config of the form: + +``` +language: scala + +env: + global: + # PGP_PASSPHRASE + - secure: "XXXXXX" + # SONA_USER + - secure: "XXXXXX" + # SONA_PASS + - secure: "XXXXXX" + +script: admin/build.sh + +jdk: + - openjdk6 + - oraclejdk8 + +notifications: + email: + - a@b.com +``` + +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., `v0.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 (e.g., `v0.1.1`) via the GitHub + web interface. + 1. The release will be published using the Scala and JVM version combinations specified + in `scalaVersionsByJvm` in `build.sbt`. + - If you need to release against a different Scala version, include the Scala version + and the JVM version to use in the tag name, separated by `#`s (e.g., `v0.1.1#2.13.0-M1#8`). + Note that the JVM version needs to be listed in `.travis.yml` for the build to run. + 1. Travis CI will schedule a build for this release. Review the build logs. + 1. Log into https://oss.sonatype.org/ and identify the staging repository. + 1. Sanity check its contents. + 1. Release staging repository to Maven and send out release announcement. diff --git a/admin/build.sh b/admin/build.sh index 3257da0..7cb5c34 100755 --- a/admin/build.sh +++ b/admin/build.sh @@ -1,19 +1,53 @@ #!/bin/bash -# prep environment for publish to sonatype staging if the HEAD commit is tagged +set -e -# git on travis does not fetch tags, but we have TRAVIS_TAG -# headTag=$(git describe --exact-match ||:) +# Builds of tagged revisions are published to sonatype staging. -if [ "$IS_PUBLISH_JDK" == "true" ] && [[ "$TRAVIS_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)? ]]; then - echo "Going to release from tag $TRAVIS_TAG!" - myVer=$(echo $TRAVIS_TAG | sed -e s/^v// | sed -e 's/_[0-9]*\.[0-9]*//') - publishVersion='set every version := "'$myVer'"' - extraTarget="publish-signed" +# Travis runs a build on new revisions and on new tags, so a tagged revision is built twice. +# Builds for a tag have TRAVIS_TAG defined, which we use for identifying tagged builds. +# Checking the local git clone would not work because git on travis does not fetch tags. +# The version number to be published is extracted from the tag, e.g., v1.2.3 publishes +# version 1.2.3 using all Scala versions in build.sbt's `crossScalaVersions`. + +# When a new, binary incompatible Scala version becomes available, a previously released version +# can be released using that new Scala version by creating a new tag containing the Scala and the +# JVM version after hashes, e.g., v1.2.3#2.13.0-M1#8. The JVM version needs to be listed in +# `.travis.yml`, otherwise the required build doesn't run. + +verPat="[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)?" +tagPat="^v$verPat(#$verPat#[0-9]+)?$" + +if [[ "$TRAVIS_TAG" =~ $tagPat ]]; then + currentJvmVer=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | sed 's/^1\.//' | sed 's/[^0-9].*//') + + tagVer=$(echo $TRAVIS_TAG | sed s/#.*// | sed s/^v//) + publishVersion='set every version := "'$tagVer'"' + + scalaAndJvmVer=$(echo $TRAVIS_TAG | sed s/[^#]*// | sed s/^#//) + if [ "$scalaAndJvmVer" != "" ]; then + scalaVer=$(echo $scalaAndJvmVer | sed s/#.*//) + jvmVer=$(echo $scalaAndJvmVer | sed s/[^#]*// | sed s/^#//) + if [ "$jvmVer" != "$currentJvmVer" ]; then + echo "Not publishing $TRAVIS_TAG on Java version $currentJvmVer." + exit 0 + fi + publishScalaVersion='set every ScalaModulePlugin.scalaVersionsByJvm := Map('$jvmVer' -> List("'$scalaVer'" -> true))' + echo "Releasing $tagVer using Scala $scalaVer on Java version $jvmVer." + else + echo "Releasing $tagVer on Java version $currentJvmVer according to 'scalaVersionsByJvm' in build.sbt." + fi + + 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_97ebac4c5d62_key + IV=$encrypted_97ebac4c5d62_iv + + openssl 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 compile test $extraTarget +sbt "$publishVersion" "$publishScalaVersion" 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..17db3f3 --- /dev/null +++ b/admin/genKeyPair.sh @@ -0,0 +1,41 @@ +#!/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 +echo Be careful when using special characters in the passphrase, see http://docs.travis-ci.com/user/encryption-keys/#Note-on-escaping-certain-symbols +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..68ae464 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) - +addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") // only added when publishing, see build.sh diff --git a/admin/publish-settings.sbt b/admin/publish-settings.sbt new file mode 100644 index 0000000..f763ea0 --- /dev/null +++ b/admin/publish-settings.sbt @@ -0,0 +1,9 @@ +def env(key: String) = Option(System.getenv(key)).getOrElse("") + +pgpPassphrase := Some(env("PGP_PASSPHRASE").toArray) + +pgpPublicRing := file("admin/pubring.asc") + +pgpSecretRing := file("admin/secring.asc") + +credentials += Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", env("SONA_USER"), env("SONA_PASS")) diff --git a/admin/pubring.asc b/admin/pubring.asc index 1a9742f..80ed091 100644 --- a/admin/pubring.asc +++ b/admin/pubring.asc @@ -1,18 +1,18 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: BCPG v1.49 -mQENBFSScxABCACj8nAMNdPBgCihD2b+ngYhQaIOmhPEG0Z394T1Qg8EawWhaWXH -50A3NaA5jc1+UJSQ0xyzB/95xCvTCCgWgo2q3L+hIQKoIif+7MfMCrw7CsZSuGFg -Jv46saoBvLBoeiSCI7cFYrQNh+gfTypgGtFu/BBjeIpl6RKQ1gyUdPSb0Nh/2hk9 -7ZdApoJ4PhLnEAB5ZA8YnakBicBMF8GRGEwBgA/Mw/ADGqGA9rYxcl/BT65dEbrV -onDDZUc1NCcMoHnpnzLzLnrYH0QK1GbE+UZ9eesQUts7ICTO/+YCpAYxHAqdCynF -mMHY86yXanF1AK8blGxeIagiLY1kJ9C/iUr1ABEBAAG0KGFzeW5jIDxzY2FsYS1p -bnRlcm5hbHNAZ29vZ2xlZ3JvdXBzLmNvbT6JARwEEwECAAYFAlSScxAACgkQhxTM -1mIV232fBAf/dbVxSfLptv7Y/y/v08LO3T+5eAhLDLWfVhS7sJUNWPBM2hxsSEw0 -9Wb1X15v8rv2nrxOmcOxbYiWxe2lVrxj8/J7GT8x/eVFQ4cQ7wAC6GhHNvXCTxEU -TnJAmJPPhlAeubK7b5UT3v3SpY/TM7QoE/i2PBb5VzZcc8cbqpanMODnJqQiIy4R -P89XX8TkskWnFIdir0L8TXGmp4UUBXyRc9KZwR9aXmu5f8U8p7t/DEIAZxqEv8Zf -Rud2i+JvFjY2pUj7uZZyeIlqQthegsF+/3M70pgLS26Fz0u7xEHOspzpsdsBAILB -/GrxK4BP32iLo+pgZBcLX/XEN0+scv1SJw== -=9Yrd +mQENBFkAWsEBCACKxZo0QyGN/T9scj8rY1vUzZX/BXEvS3EM7j4dsnzaruU4uohG +HMRRooz5Mm03OqaQyC+Ckuo2J0rhND1W/RYBK8g2w7zcdxlqWGq10qXEfaxmWKS3 +kPpWlbzZb+TvPsesLw6HI82oqsSIEl4C8bsy/jH6f3kOnxiUTYYEt5yL9G7P3DyE +5z2sLOapOofIZeyUBU90pT4Km/09hI0AaWaHYQRRVVFhA5RlxidEB5X4eQ6QLA7C +D6iiKtou/Jg0iWY/1aliCwkZHm9J4x8zoQpSvKKaODhKaDia55ltkC5w2sT6xdnK +Q2yasSbHp/RHCFE3jN8AN4CwIy5UWconsi7fABEBAAG0KGFzeW5jIDxzY2FsYS1p +bnRlcm5hbHNAZ29vZ2xlZ3JvdXBzLmNvbT6JARwEEwECAAYFAlkAWsEACgkQOqT/ +ZELU8HwpgwgAhbwhNUKSLWK+75rVCEBdwgIgr0gYDXWnFURdAoubIT+3BWy3WZwB +DkceCM2yssnKxxJYd07xvFyNVVZRofmgi/A7qq7XFt3PIxd6NDytbWtHf0Y4N3AI +oksJpsHZDJBz2O06WGROi9tisIB/JypsGX5YmY0DJBnUU7zZIHE/DC0+83eB2DlM +Irxguyrd7J6/jDpNWKhLoWRdsGkeukbxExFUP99yRJ+K+itUHIWAe6/pGUNINW7E +HgDmDBUtyiYNlwVU43CgAHUuqL6U+bZwUBPmd5Ru7aNJ30Nrd42cuw5GmJk7CLHN +dVUFP89RuQEioYdcgfDOIRo9rUyJ8fq+Zw== +=9prU -----END PGP PUBLIC KEY BLOCK----- diff --git a/admin/secring.asc.enc b/admin/secring.asc.enc Binary files differindex 114d368..89469a3 100644 --- a/admin/secring.asc.enc +++ b/admin/secring.asc.enc |