Skip to content

Commit 82c145e

Browse files
committed
Infrastructure for tag-based publishing
1 parent 425dd73 commit 82c145e

File tree

11 files changed

+244
-24
lines changed

11 files changed

+244
-24
lines changed

.travis.yml

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1-
#sudo: false
2-
#addons:
3-
# apt:
4-
# packages:
5-
# - oracle-java8-installer
61
language: scala
2+
73
scala:
84
- 2.11.12
95
- 2.12.6
106
- 2.13.0-pre-abf21b9
117
jdk:
128
- oraclejdk8
139
env:
14-
- SCALAJS_VERSION=
15-
- SCALAJS_VERSION=0.6.22
16-
- SCALAJS_VERSION=1.0.0-M3
10+
global:
11+
# PGP_PASSPHRASE
12+
- secure: "rjetmX9HXoN/scxTCBFCHIUDFryY0Yd29sR6EBrW/2tCOILO09RTCcJB0kPn2YMZ9en8ChTtOpqGF9133f6wZ7/ZINSUt1tNwnbgDlhGbwJW2WFTUEmL7ScdqmgRGa294aVuAfrvJnr+dN92it6ibAB8nThgsjq0LnZREJsKwQ77vvEeATEKutuPLGlrHrmqL7/XCjb2uYz9Xh0sSpyQlKOGt5EN7JzM/Bzyju+RYS9BvnLVV86fey/UWO1DNDa4MU5835akevqvtwN7CpCFxFKgbfc+40bAh7Xc59UnkxP+Lcs2KxJx9heS6RJJiNEx99r59LL2JALyN++yOAS97HEfii4Yc3OK9VRZCNQFW4gNm3VtGNW4EC+LOX/9cUiUNg2J65nY0UF2d6R3vsqiCKaK6C0cm+jIs3fgDHFlB+MiHC/ZECaoPvwzm1AxQMIWyoFFqXuHQk3Ef137G0x1ejneUoGD/PqMbiEAX64+VVvOxgOI2/jyt4hFTEk6JiWVahmk+7oFAsLH1n9J1Y3csMvmo9S0S/Ey9D3bR07hggc8pj/CJPj9gFSfpGEVhroc37T/VlP23EVJgpteovERyeJGC3P7wVWvi1pNNW6iOVENzY1GkHlHkJUI7Q4B+eIW2mh5wi6JyC/DM2lO4z3M2KQkNqQgzIBdm5p/4hezkkA="
13+
# SONA_USER
14+
- secure: "oStf8s+LwXcmVENMnWU970OAImwXLV2E6FNXSLE7zdr4YL70cWVsDXDeAs0LSEmiOXTtHulmcIwUt6fCqZ1aiTxUxGX2avy0DSM9nCrQit7IXfwX8V9iK9/3t/SXo1g8yEfxyug+OK6CKOlLeA9HY/TJjO6fkYCsR1NrD8PLpgGtgSwS1GGjifbdahkQyyyivxROJ2UaRysm8PJ1X1966FoQoXKLU4HEztO48y3ZIlItZGwVv/1FJ18AniU2oCnV6XQVM+OB/j+IxNENzLBvd54/YjVtRRa22KTlC8j/NXo8Vq/f0ZhLjNLzYIEB1ER+2T2dthpek+Y8eMR5RdHrFj4Xp2kB04K70ZIL6pw2BDpqeiabjm1E3X6c+flj4pWR5p8uXguV7JmhYgl9d2UEqP7ZTzSbgh2S2WG9EjyK4C2L9jimgBP+Nih2yeW8GuURKgjQ5zrg3+7vxXqBjNN4PmTLpGiQ5shK1kZCpzdgfTl3LfUO4Uitg2Vl8yFC3Z9d3Fo5oV84DhL20pMIx7CtIcMX4b5QHArbUyICYFOvuz+8qP67kTPLVoErNmKWjqpp64VarqfoVbbe4NwRgGuNSMPR1nHb1LjloXv1CiNs9AocvnTknhV1T9I4F4XWi/J6mEwUbVW7GppzqszO6cAgcPLbqp92U8I+rexPjiieCZ0="
15+
# SONA_PASS
16+
- secure: "m0Fw/eH7RXJJoBTfqV6CMd7kaIN2pRPnQPNXJGb546UjqYAlYTkfjvVrWpsgpisRBptI1FEHn24yGbgAHjIes/4un/O62K66I0BffL8PbdeHeNcDjSrTesKEqage2mQfGOiqccVsmkgiKeXNYL8tPZRmPQQ3XZ97mS1SXWlqAJSMW6HfNnvqW14Gdb/snR6I8lQ2o5tRnLerWPnI96pp+xjZca2lD4XDvH2wLJXXLmYY61e23ZYzZMepxBxhGa7js3YTYzCWNrOfBLjFJ5nwRxbjR0WMuz5z5Gdy715WtguKS4Fffd/GJHycLROBU9LCAQDMTxMFvqzFqVFpfq0BuTmmkXFXj+a7dO+ABG0RfoDfoMjn7pHwyHNCZyMMuR1HCjMkbGFwC+Zme2UAYNivtcsuWWeMuypwjyqjfFfNns4FHJ0SXFtC/6+OJkAuUdbEJKReYWKWEsP5SnCH/8PLlc+uUl3tjQkFLc1sOAyx9cTWyBErwuJXhgTrjT9AWvO+fvhcm8z/p5+aaF/U9GIrzPqziX4hGjzc/WC+rsFJSiBDlFQl7br+m8WWs7/wuXqPGXmhf0BNQViDi7fZndDHcY3p3T0An05d/IMKjCUrgLDlJi6VYs9XN7S8ay6MH+XTwIsJGSxtGjfEO4rHGIjtR2GRr8TqdNfnpsI3ucbia1Y="
17+
matrix:
18+
- SCALAJS_VERSION=
19+
- SCALAJS_VERSION=0.6.22
20+
- SCALAJS_VERSION=1.0.0-M3
21+
1722
matrix:
1823
exclude:
1924
- scala: 2.13.0-pre-abf21b9
@@ -23,14 +28,17 @@ matrix:
2328
include:
2429
- scala: 2.12.6
2530
env: TEST_SCALAFIX=true
26-
before_script:
27-
- ./checkCLA.sh
31+
32+
before_script: ./checkCLA.sh
2833
script:
29-
- |
30-
if [[ $TEST_SCALAFIX == "true" ]]; then
31-
cd scalafix && sbt input/compile output/compile tests/test
32-
elif [[ $SCALAJS_VERSION == "" ]]; then
33-
sbt ++$TRAVIS_SCALA_VERSION scala-collection-compat/test
34-
else
35-
sbt ++$TRAVIS_SCALA_VERSION scala-collection-compatJS/test
36-
fi
34+
- export RELEASE_COMBO=true
35+
- admin/build.sh
36+
37+
before_cache:
38+
- find $HOME/.sbt -name "*.lock" | xargs rm
39+
- find $HOME/.ivy2/cache -name "ivydata-*.properties" | xargs rm
40+
cache:
41+
directories:
42+
- $HOME/.ivy2/cache
43+
- $HOME/.sbt/boot
44+
- $HOME/.sbt/launchers

admin/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
## Tag Driven Releasing
2+
3+
### Initial setup for the repository
4+
5+
To configure tag driven releases from Travis CI.
6+
7+
1. Generate a key pair for this repository with `./admin/genKeyPair.sh`.
8+
Edit `.travis.yml` and `admin/build.sh` as prompted.
9+
1. Publish the public key to https://pgp.mit.edu
10+
1. Store other secrets as encrypted environment variables with `./admin/encryptEnvVars.sh`.
11+
Edit `.travis.yml` as prompted.
12+
1. Edit `.travis.yml` to use `./admin/build.sh` as the build script,
13+
and edit that script to use the tasks required for this project.
14+
Ensure that `RELEASE_COMBO` is `true` for build matrix combinations
15+
that should be released to sonatype (when building a tag).
16+
17+
18+
It is important to add comments in `.travis.yml` to identify the name
19+
of each environment variable encoded in a `secure` section.
20+
21+
After these steps, your `.travis.yml` should contain config of the form:
22+
23+
```
24+
language: scala
25+
26+
jdk:
27+
- openjdk6
28+
- oraclejdk8
29+
30+
scala:
31+
- 2.11.12
32+
- 2.12.6
33+
34+
env:
35+
global:
36+
# PGP_PASSPHRASE
37+
- secure: "XXXXXX"
38+
# SONA_USER
39+
- secure: "XXXXXX"
40+
# SONA_PASS
41+
- secure: "XXXXXX"
42+
43+
script:
44+
- if [[ "$TRAVIS_JDK_VERSION" == "openjdk6" && "$TRAVIS_SCALA_VERSION" =~ "2\.11.*" || "$TRAVIS_JDK_VERSION" == "openjdk6" && "$TRAVIS_SCALA_VERSION" =~ "2\.12.*" ]]; then export RELEASE_COMBO=true; fi
45+
- admin/build.sh
46+
47+
notifications:
48+
email:
49+
50+
```
51+
52+
If Sonatype credentials change in the future, step 3 can be repeated
53+
without generating a new key.
54+
55+
### Testing
56+
57+
1. Follow the release process below to create a dummy release (e.g., `v0.1.0-TEST1`).
58+
Confirm that the release was staged to Sonatype but do not release it to Maven
59+
central. Instead, drop the staging repository.
60+
61+
### Performing a release
62+
63+
1. Create a GitHub "Release" with a corresponding tag (e.g., `v0.1.1`) via the GitHub
64+
web interface.
65+
1. The release will be published using the Scala and JVM version combinations specified
66+
in the travis build matrix where `[ "$RELEASE_COMBO" = "true" ]`.
67+
- If you need to release against a different Scala version, create a new commit that modifies
68+
`.travis.yml` and push a new tag, e.g., `v1.2.3#2.13.0-M5`. The suffix after `#` is ignored.
69+
1. Travis CI will schedule a build for this release. Review the build logs.
70+
1. Log into https://oss.sonatype.org/ and identify the staging repository.
71+
1. Sanity check its contents.
72+
1. Release staging repository to Maven and send out release announcement.

admin/build.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Builds of tagged revisions are published to sonatype staging.
6+
7+
# Travis runs a build on new revisions and on new tags, so a tagged revision is built twice.
8+
# Builds for a tag have TRAVIS_TAG defined, which we use for identifying tagged builds.
9+
# Checking the local git clone would not work because git on travis does not fetch tags.
10+
11+
# The version number to be published is extracted from the tag, e.g., v1.2.3 publishes
12+
# version 1.2.3 on all combinations of the travis matrix where `[ "$RELEASE_COMBO" = "true" ]`.
13+
14+
# In order to build a previously released version against a new (binary incompatible) Scala release,
15+
# a new commit that modifies (and prunes) the Scala versions in .travis.yml needs to be added on top
16+
# of the existing tag. Then a new tag can be created for that commit, e.g., `v1.2.3#2.13.0-M5`.
17+
# Everything after the `#` in the tag name is ignored.
18+
19+
if [[ "$TEST_SCALAFIX" == "true" ]]; then
20+
cd scalafix && sbt input/compile output/compile tests/test
21+
exit 0
22+
fi
23+
24+
if [ "$SCALAJS_VERSION" = "" ]; then
25+
projectPrefix="scala-collection-compat"
26+
else
27+
projectPrefix="scala-collection-compatJS"
28+
fi
29+
30+
verPat="[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9-]+)?"
31+
tagPat="^v$verPat(#.*)?$"
32+
33+
if [[ "$TRAVIS_TAG" =~ $tagPat ]]; then
34+
tagVer=$(echo $TRAVIS_TAG | sed s/#.*// | sed s/^v//)
35+
publishVersion='set every version := "'$tagVer'"'
36+
37+
if [ "$RELEASE_COMBO" = "true" ]; then
38+
currentJvmVer=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | sed 's/^1\.//' | sed 's/[^0-9].*//')
39+
echo "Releasing $tagVer with Scala $TRAVIS_SCALA_VERSION on Java version $currentJvmVer."
40+
41+
publishTask="$projectPrefix/publish-signed"
42+
43+
cat admin/gpg.sbt >> project/plugins.sbt
44+
cp admin/publish-settings.sbt .
45+
46+
# Copied from the output of genKeyPair.sh
47+
K=$encrypted_8c7005201bb0_key
48+
IV=$encrypted_8c7005201bb0_iv
49+
openssl aes-256-cbc -K $K -iv $IV -in admin/secring.asc.enc -out admin/secring.asc -d
50+
fi
51+
fi
52+
53+
sbt "++$TRAVIS_SCALA_VERSION" "$publishVersion" "$projectPrefix/clean" "$projectPrefix/test" "$projectPrefix/publishLocal" "$publishTask"

admin/encryptEnvVars.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
#
3+
# Encrypt sonatype credentials so that they can be
4+
# decrypted in trusted builds on Travis CI.
5+
#
6+
set -e
7+
8+
read -s -p 'SONA_USER: ' SONA_USER
9+
travis encrypt SONA_USER="$SONA_USER"
10+
read -s -p 'SONA_PASS: ' SONA_PASS
11+
travis encrypt SONA_PASS="$SONA_PASS"

admin/genKeyPair.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
#
3+
# Generates a key pair for this repository to sign artifacts.
4+
# Encrypt the private key and its passphrase in trusted builds
5+
# on Travis CI.
6+
#
7+
set -e
8+
9+
# Based on https://gist.github.com/kzap/5819745:
10+
function promptDelete() {
11+
if [[ -f "$1" ]]; then
12+
echo About to delete $1, Enter for okay / CTRL-C to cancel
13+
read
14+
rm "$1"
15+
fi
16+
}
17+
for f in admin/secring.asc.enc admin/secring.asc admin/pubring.asc; do promptDelete "$f"; done
18+
19+
echo Generating key pair. Please enter 1. repo name 2. [email protected], 3. a new passphrase
20+
echo Be careful when using special characters in the passphrase, see http://docs.travis-ci.com/user/encryption-keys/#Note-on-escaping-certain-symbols
21+
cp admin/gpg.sbt project
22+
sbt 'set pgpReadOnly := false' \
23+
'set pgpPublicRing := file("admin/pubring.asc")' \
24+
'set pgpSecretRing := file("admin/secring.asc")' \
25+
'pgp-cmd gen-key'
26+
rm project/gpg.sbt
27+
28+
echo ============================================================================================
29+
echo Encrypting admin/secring.asc. Update K and IV variables in admin/build.sh accordingly.
30+
echo ============================================================================================
31+
travis encrypt-file admin/secring.asc
32+
rm admin/secring.asc
33+
mv secring.asc.enc admin
34+
35+
echo ============================================================================================
36+
echo Encrypting environment variables. Add each to a line in .travis.yml. Include a comment
37+
echo with the name of the corresponding variable
38+
echo ============================================================================================
39+
read -s -p 'PGP_PASSPHRASE: ' PGP_PASSPHRASE
40+
travis encrypt PGP_PASSPHRASE="$PGP_PASSPHRASE"
41+

admin/gpg.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") // only added when publishing, see build.sh

admin/publish-settings.sbt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
def env(key: String) = Option(System.getenv(key)).getOrElse("")
2+
3+
inThisBuild(Seq(
4+
pgpPassphrase := Some(env("PGP_PASSPHRASE").toArray),
5+
pgpPublicRing := file("admin/pubring.asc"),
6+
pgpSecretRing := file("admin/secring.asc"),
7+
credentials += Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", env("SONA_USER"), env("SONA_PASS"))
8+
))

admin/pubring.asc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-----BEGIN PGP PUBLIC KEY BLOCK-----
2+
Version: BCPG v1.49
3+
4+
mQENBFry+hgBCAC112OGoMdQXMAEEWiReEc207hWcD5BAO/UnSxUj6kn5UDUd1k3
5+
9iSjdlyVkCheztuRhLmPdmBX3L4gzTj1bFCSmWg/HmRwDQY1kJ7jZrhymj+HOqe+
6+
RfLE3CCCiodmKEB02XhlCupoNlrWRDRb3vxlbLkWL84bA/yFFxhmcNZotSZ0D7r3
7+
1wgkU06EKdxPkGGU25tp8jeZZ3HL3f9MQDOkjhJOP4cA6iAhuzHf0gQnn9BGy8Co
8+
MlCCRrxHpilwnqPa73tL1kHiCWKnbVRiasX9zI/+WEMOKFJW781R8BwIqprbZHrm
9+
sV0mLGCsUtV2dHayrplv6fs0xkn6vfeMAbn/ABEBAAG0OnNjYWxhLWNvbGxlY3Rp
10+
b24tY29tcGF0IDxzY2FsYS1pbnRlcm5hbHNAZ29vZ2xlZ3JvdXBzLmNvbT6JARwE
11+
EwECAAYFAlry+hgACgkQwWgQ0Nj6Z3y1aggAiV+AgfTmGJXi7kOfQ46XasrIXBkW
12+
PrFW8vVNS+qpvzriZg6YEU3n7XtkU396cUwx50s4kDBfUqlBKLL9jSwdI8tcDXE6
13+
vn4EN3ISSpQWNF7rFbfxDs+4+cebbEEsWLLbS3gqyuaoukeJ40ieTIkUCVk4ZVZY
14+
26K/PooUZ8MQZPg0jNpMHRUi+RC5JKiD8pTEd5S53nfWaJF8McfA+zDnuY8/2AML
15+
Ou/c205J862J/ymGAu6U3+LCkN6DhQ9C07ymBYGErL9q3zyhyNv83zVov+b/iosW
16+
hZ/rZEUKU6a4Qfg+KpZiykvh1cszBBbljVSbbzb4qZJKcgkJk4Nrynsh6w==
17+
=tItJ
18+
-----END PGP PUBLIC KEY BLOCK-----

admin/secring.asc.enc

1.84 KB
Binary file not shown.

build.sbt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
import sbtcrossproject.{crossProject, CrossType}
2+
import ScalaModulePlugin._
23

3-
inThisBuild(Def.settings(
4-
organization := "org.scala-lang",
5-
version := "0.1-SNAPSHOT",
4+
inThisBuild(Seq(
65
resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-integration/",
7-
crossScalaVersions := Seq("2.12.6", "2.13.0-pre-abf21b9", "2.11.12"),
8-
scalaVersion := crossScalaVersions.value.head,
9-
scalacOptions ++= Seq("-feature", "-language:higherKinds", "-language:implicitConversions")
6+
crossScalaVersions := Seq("2.12.6", "2.13.0-pre-abf21b9", "2.11.12")
107
))
118

129
lazy val `scala-collection-compat` = crossProject(JSPlatform, JVMPlatform)
1310
.withoutSuffixFor(JVMPlatform)
1411
.crossType(CrossType.Pure)
1512
.in(file("."))
13+
.settings(scalaModuleSettings)
14+
.jvmSettings(scalaModuleSettingsJVM)
1615
.settings(
1716
name := "scala-collection-compat",
17+
version := "0.1-SNAPSHOT",
18+
scalacOptions ++= Seq("-feature", "-language:higherKinds", "-language:implicitConversions"),
1819
unmanagedSourceDirectories in Compile += {
1920
val sharedSourceDir = baseDirectory.value.getParentFile / "src/main"
2021
if (scalaVersion.value.startsWith("2.13.")) sharedSourceDir / "scala-2.13"
2122
else sharedSourceDir / "scala-2.11_2.12"
2223
}
2324
)
2425
.jvmSettings(
26+
// TODO: should we add this?
27+
// OsgiKeys.exportPackage := Seq(s"scala.collection.compat.*;version=${version.value}"),
2528
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test"
2629
)
30+
.jsSettings(
31+
fork in Test := false // Scala.js cannot run forked tests
32+
)
2733
.jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))
2834

2935
lazy val `scala-collection-compatJVM` = `scala-collection-compat`.jvm

0 commit comments

Comments
 (0)