diff --git a/project/Appveyor.scala b/project/Appveyor.scala new file mode 100644 index 000000000..f0983e17f --- /dev/null +++ b/project/Appveyor.scala @@ -0,0 +1,31 @@ +import argonaut._ +import argonaut.Argonaut._ +import argonaut.ArgonautShapeless._ + +import sbt.Logger + +object Appveyor { + + final case class Build( + buildId: Long, + branch: String, + commitId: String, + status: String + ) + + def branchLastBuild(repo: String, branch: String, log: Logger): Build = { + + final case class Response(build: Build) + + val url = s"https://ci.appveyor.com/api/projects/$repo/branch/$branch" + val rawResp = HttpUtil.fetch(url, log) + + rawResp.decodeEither[Response] match { + case Left(err) => + sys.error(s"Error decoding response from $url: $err") + case Right(resp) => + resp.build + } + } + +} diff --git a/project/HttpUtil.scala b/project/HttpUtil.scala new file mode 100644 index 000000000..1cc3637bf --- /dev/null +++ b/project/HttpUtil.scala @@ -0,0 +1,57 @@ +import java.io.{ByteArrayOutputStream, InputStream} +import java.net.{HttpURLConnection, URL, URLConnection} +import java.nio.charset.StandardCharsets + +import sbt.Logger + +object HttpUtil { + + private def readFully(is: InputStream): Array[Byte] = { + val buffer = new ByteArrayOutputStream + val data = Array.ofDim[Byte](16384) + + var nRead = 0 + while ({ + nRead = is.read(data, 0, data.length) + nRead != -1 + }) + buffer.write(data, 0, nRead) + + buffer.flush() + buffer.toByteArray + } + + def fetch(url: String, log: Logger): String = { + + val url0 = new URL(url) + + log.info(s"Fetching $url") + + val (rawResp, code) = { + + var conn: URLConnection = null + var httpConn: HttpURLConnection = null + var is: InputStream = null + + try { + conn = url0.openConnection() + httpConn = conn.asInstanceOf[HttpURLConnection] + httpConn.setRequestProperty("Accept", "application/vnd.travis-ci.2+json") + is = conn.getInputStream + + (readFully(is), httpConn.getResponseCode) + } finally { + if (is != null) + is.close() + if (httpConn != null) + httpConn.disconnect() + } + } + + if (code / 100 != 2) + sys.error(s"Unexpected response code when getting $url: $code") + + new String(rawResp, StandardCharsets.UTF_8) + } + +} diff --git a/project/Release.scala b/project/Release.scala index 1d470aec5..38fd0ef7d 100644 --- a/project/Release.scala +++ b/project/Release.scala @@ -44,6 +44,23 @@ object Release { state } + val checkAppveyorStatus = ReleaseStep { state => + + val currentHash = state.vcs.currentHash + + val build = Appveyor.branchLastBuild("alexarchambault/coursier-a7n6k", "master", state.log) + + state.log.info(s"Found last build ${build.buildId} for branch master, status: ${build.status}") + + if (build.commitId != currentHash) + sys.error(s"Last master Appveyor build corresponds to commit ${build.commitId}, expected $currentHash") + + if (build.status != "success") + sys.error(s"Last master Appveyor build status: ${build.status}") + + state + } + val previousReleaseVersion = AttributeKey[String]("previousReleaseVersion") val initialVersion = AttributeKey[String]("initialVersion") @@ -242,6 +259,7 @@ object Release { val settings = Seq( releaseProcess := Seq[ReleaseStep]( checkTravisStatus, + checkAppveyorStatus, savePreviousReleaseVersion, checkSnapshotDependencies, inquireVersions, diff --git a/project/Travis.scala b/project/Travis.scala index f02386a2b..e6878d2b3 100644 --- a/project/Travis.scala +++ b/project/Travis.scala @@ -1,7 +1,3 @@ -import java.io.{ByteArrayOutputStream, InputStream} -import java.net.{HttpURLConnection, URL, URLConnection} -import java.nio.charset.StandardCharsets - import argonaut._ import argonaut.Argonaut._ import argonaut.ArgonautShapeless._ @@ -56,58 +52,10 @@ object Travis { ) - private def readFully(is: InputStream): Array[Byte] = { - val buffer = new ByteArrayOutputStream - val data = Array.ofDim[Byte](16384) - - var nRead = 0 - while ({ - nRead = is.read(data, 0, data.length) - nRead != -1 - }) - buffer.write(data, 0, nRead) - - buffer.flush() - buffer.toByteArray - } - - private def fetch(url: String, log: Logger): String = { - - val url0 = new URL(url) - - log.info(s"Fetching $url") - - val (rawResp, code) = { - - var conn: URLConnection = null - var httpConn: HttpURLConnection = null - var is: InputStream = null - - try { - conn = url0.openConnection() - httpConn = conn.asInstanceOf[HttpURLConnection] - httpConn.setRequestProperty("Accept", "application/vnd.travis-ci.2+json") - is = conn.getInputStream - - (readFully(is), httpConn.getResponseCode) - } finally { - if (is != null) - is.close() - if (httpConn != null) - httpConn.disconnect() - } - } - - if (code / 100 != 2) - sys.error(s"Unexpected response code when getting $url: $code") - - new String(rawResp, StandardCharsets.UTF_8) - } - def builds(repo: String, log: Logger): List[Build] = { val url = s"https://api.travis-ci.org/repos/$repo/builds" - val resp = fetch(url, log) + val resp = HttpUtil.fetch(url, log) resp.decodeEither[Builds] match { case Left(err) => @@ -121,7 +69,7 @@ object Travis { def job(id: JobId, log: Logger): Job = { val url = s"https://api.travis-ci.org/jobs/${id.value}" - val resp = fetch(url, log) + val resp = HttpUtil.fetch(url, log) resp.decodeEither[Job] match { case Left(err) =>