Add scripted release
This commit is contained in:
parent
7db3f62ff5
commit
ceb888b9a7
11 changed files with 412 additions and 179 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
{% extends "basic/layout.html" %}
|
{% extends "basic/layout.html" %}
|
||||||
{% set script_files = script_files + ['_static/theme_extras.js'] %}
|
{% set script_files = script_files + ['_static/theme_extras.js'] %}
|
||||||
{% set css_files = css_files + ['_static/print.css'] %}
|
{% set css_files = css_files + ['_static/print.css'] %}
|
||||||
|
{% set is_snapshot = version.endswith("-SNAPSHOT") %}
|
||||||
|
|
||||||
{# do not display relbars #}
|
{# do not display relbars #}
|
||||||
{% block relbar1 %}{% endblock %}
|
{% block relbar1 %}{% endblock %}
|
||||||
|
|
@ -37,7 +38,11 @@
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<h1 class="heading"><a href="{{ pathto('index') }}"><span>{{ shorttitle|e }}</span></a></h1>
|
<h1 class="heading"><a href="{{ pathto('index') }}"><span>{{ shorttitle|e }}</span></a></h1>
|
||||||
<h2 class="heading"><a href="{{ pathto('index') }}"><span>Version {{ version|e }}</span></a></h2>
|
<h2 class="heading"><a href="{{ pathto('index') }}"><span>Version {{ version|e }}</span></a></h2>
|
||||||
|
{%- if is_snapshot -%}
|
||||||
<h2 class="rightheading"><span><a href="http://akka.io/docs/akka/snapshot/Akka.pdf">PDF</a></span></h2>
|
<h2 class="rightheading"><span><a href="http://akka.io/docs/akka/snapshot/Akka.pdf">PDF</a></span></h2>
|
||||||
|
{%- else -%}
|
||||||
|
<h2 class="rightheading"><span><a href="http://akka.io/docs/akka/{{ version|e }}/Akka.pdf">PDF</a></span></h2>
|
||||||
|
{%- endif -%}
|
||||||
{%- endblock %}
|
{%- endblock %}
|
||||||
</div>
|
</div>
|
||||||
<div class="topnav">
|
<div class="topnav">
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ object AkkaBuild extends Build {
|
||||||
lazy val akka = Project(
|
lazy val akka = Project(
|
||||||
id = "akka",
|
id = "akka",
|
||||||
base = file("."),
|
base = file("."),
|
||||||
settings = parentSettings ++ Unidoc.settings ++ rstdocSettings ++ Seq(
|
settings = parentSettings ++ Release.settings ++ Unidoc.settings ++ Rstdoc.settings ++ Publish.versionSettings ++ Seq(
|
||||||
parallelExecution in GlobalScope := false,
|
parallelExecution in GlobalScope := false,
|
||||||
Unidoc.unidocExclude := Seq(samples.id, tutorials.id),
|
Publish.defaultPublishTo in ThisBuild <<= crossTarget / "repository",
|
||||||
rstdocDirectory <<= baseDirectory / "akka-docs"
|
Unidoc.unidocExclude := Seq(samples.id, tutorials.id)
|
||||||
),
|
),
|
||||||
aggregate = Seq(actor, testkit, actorTests, stm, remote, slf4j, amqp, mailboxes, akkaSbtPlugin, samples, tutorials, docs)
|
aggregate = Seq(actor, testkit, actorTests, stm, remote, slf4j, amqp, mailboxes, akkaSbtPlugin, samples, tutorials, docs)
|
||||||
)
|
)
|
||||||
|
|
@ -266,7 +266,7 @@ object AkkaBuild extends Build {
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
|
|
||||||
override lazy val settings = super.settings ++ buildSettings ++ Publish.versionSettings
|
override lazy val settings = super.settings ++ buildSettings
|
||||||
|
|
||||||
lazy val baseSettings = Defaults.defaultSettings ++ Publish.settings
|
lazy val baseSettings = Defaults.defaultSettings ++ Publish.settings
|
||||||
|
|
||||||
|
|
@ -349,23 +349,6 @@ object AkkaBuild extends Build {
|
||||||
compileInputs in MultiJvm <<= (compileInputs in MultiJvm) dependsOn (ScalariformKeys.format in MultiJvm),
|
compileInputs in MultiJvm <<= (compileInputs in MultiJvm) dependsOn (ScalariformKeys.format in MultiJvm),
|
||||||
ScalariformKeys.preferences in MultiJvm := formattingPreferences
|
ScalariformKeys.preferences in MultiJvm := formattingPreferences
|
||||||
)
|
)
|
||||||
|
|
||||||
// reStructuredText docs
|
|
||||||
|
|
||||||
val rstdocDirectory = SettingKey[File]("rstdoc-directory")
|
|
||||||
val rstdoc = TaskKey[File]("rstdoc", "Build the reStructuredText documentation.")
|
|
||||||
|
|
||||||
lazy val rstdocSettings = Seq(rstdoc <<= rstdocTask)
|
|
||||||
|
|
||||||
def rstdocTask = (rstdocDirectory, streams) map {
|
|
||||||
(dir, s) => {
|
|
||||||
s.log.info("Building reStructuredText documentation...")
|
|
||||||
val exitCode = Process(List("make", "clean", "html", "pdf"), dir) ! s.log
|
|
||||||
if (exitCode != 0) sys.error("Failed to build docs.")
|
|
||||||
s.log.info("Done building docs.")
|
|
||||||
dir
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
package akka
|
package akka
|
||||||
|
|
||||||
import sbt._
|
import sbt._
|
||||||
import Keys._
|
import sbt.Keys._
|
||||||
|
import sbt.Project.Initialize
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object Publish {
|
object Publish {
|
||||||
final val Snapshot = "-SNAPSHOT"
|
final val Snapshot = "-SNAPSHOT"
|
||||||
|
|
||||||
|
val defaultPublishTo = SettingKey[File]("default-publish-to")
|
||||||
|
|
||||||
lazy val settings = Seq(
|
lazy val settings = Seq(
|
||||||
crossPaths := false,
|
crossPaths := false,
|
||||||
pomExtra := akkaPomExtra,
|
pomExtra := akkaPomExtra,
|
||||||
publishTo := akkaPublishTo,
|
publishTo <<= akkaPublishTo,
|
||||||
credentials ++= akkaCredentials,
|
credentials ++= akkaCredentials,
|
||||||
organizationName := "Typesafe Inc.",
|
organizationName := "Typesafe Inc.",
|
||||||
organizationHomepage := Some(url("http://www.typesafe.com"))
|
organizationHomepage := Some(url("http://www.typesafe.com"))
|
||||||
|
|
@ -32,11 +35,12 @@ object Publish {
|
||||||
</licenses>
|
</licenses>
|
||||||
}
|
}
|
||||||
|
|
||||||
def akkaPublishTo: Option[Resolver] = {
|
def akkaPublishTo: Initialize[Option[Resolver]] = {
|
||||||
val property = Option(System.getProperty("akka.publish.repository"))
|
defaultPublishTo { default =>
|
||||||
val repo = property map { "Akka Publish Repository" at _ }
|
val property = Option(System.getProperty("akka.publish.repository"))
|
||||||
val m2repo = Path.userHome / ".m2" /"repository"
|
val repo = property map { "Akka Publish Repository" at _ }
|
||||||
repo orElse Some(Resolver.file("Local Maven Repository", m2repo))
|
repo orElse Some(Resolver.file("Default Local Repository", default))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def akkaCredentials: Seq[Credentials] = {
|
def akkaCredentials: Seq[Credentials] = {
|
||||||
|
|
@ -44,17 +48,11 @@ object Publish {
|
||||||
property map (f => Credentials(new File(f))) toSeq
|
property map (f => Credentials(new File(f))) toSeq
|
||||||
}
|
}
|
||||||
|
|
||||||
def stampVersion = Command.command("stamp-version") { state =>
|
// timestamped versions
|
||||||
append((version in ThisBuild ~= stamp) :: Nil, state)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: replace with extracted.append when updated to sbt 0.10.1
|
def stampVersion = Command.command("stamp-version") { state =>
|
||||||
def append(settings: Seq[Setting[_]], state: State): State = {
|
|
||||||
val extracted = Project.extract(state)
|
val extracted = Project.extract(state)
|
||||||
import extracted._
|
extracted.append(List(version in ThisBuild ~= stamp), state)
|
||||||
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings)
|
|
||||||
val newStructure = Load.reapply(session.original ++ append, structure)
|
|
||||||
Project.setProject(session, newStructure, state)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def stamp(version: String): String = {
|
def stamp(version: String): String = {
|
||||||
|
|
|
||||||
34
project/Release.scala
Normal file
34
project/Release.scala
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
package akka
|
||||||
|
|
||||||
|
import sbt._
|
||||||
|
import sbt.Keys._
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object Release {
|
||||||
|
val releaseDirectory = SettingKey[File]("release-directory")
|
||||||
|
|
||||||
|
lazy val settings: Seq[Setting[_]] = commandSettings ++ Seq(
|
||||||
|
releaseDirectory <<= crossTarget / "release"
|
||||||
|
)
|
||||||
|
|
||||||
|
lazy val commandSettings = Seq(
|
||||||
|
commands += buildReleaseCommand
|
||||||
|
)
|
||||||
|
|
||||||
|
def buildReleaseCommand = Command.command("build-release") { state =>
|
||||||
|
val extracted = Project.extract(state)
|
||||||
|
val release = extracted.get(releaseDirectory)
|
||||||
|
val releaseVersion = extracted.get(version)
|
||||||
|
val projectRef = extracted.get(thisProjectRef)
|
||||||
|
val repo = extracted.get(Publish.defaultPublishTo)
|
||||||
|
val state1 = extracted.runAggregated(publish in projectRef, state)
|
||||||
|
val (state2, api) = extracted.runTask(Unidoc.unidoc, state1)
|
||||||
|
val (state3, docs) = extracted.runTask(Rstdoc.rstdoc, state2)
|
||||||
|
IO.delete(release)
|
||||||
|
IO.createDirectory(release)
|
||||||
|
IO.copyDirectory(repo, release / "releases")
|
||||||
|
IO.copyDirectory(api, release / "api" / "akka" / releaseVersion)
|
||||||
|
IO.copyDirectory(docs, release / "docs" / "akka" / releaseVersion)
|
||||||
|
state3
|
||||||
|
}
|
||||||
|
}
|
||||||
34
project/Rstdoc.scala
Normal file
34
project/Rstdoc.scala
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
package akka
|
||||||
|
|
||||||
|
import sbt._
|
||||||
|
import sbt.Keys._
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object Rstdoc {
|
||||||
|
val rstdocDirectory = SettingKey[File]("rstdoc-directory")
|
||||||
|
val rstdocTarget = SettingKey[File]("rstdoc-target")
|
||||||
|
val rstdoc = TaskKey[File]("rstdoc", "Build the reStructuredText documentation.")
|
||||||
|
|
||||||
|
lazy val settings = Seq(
|
||||||
|
rstdocDirectory <<= baseDirectory / "akka-docs",
|
||||||
|
rstdocTarget <<= crossTarget / "rstdoc",
|
||||||
|
rstdoc <<= rstdocTask
|
||||||
|
)
|
||||||
|
|
||||||
|
def rstdocTask = (rstdocDirectory, rstdocTarget, streams) map {
|
||||||
|
(dir, target, s) => {
|
||||||
|
s.log.info("Building reStructuredText documentation...")
|
||||||
|
val logger = new ProcessLogger {
|
||||||
|
def info(o: => String): Unit = s.log.debug(o)
|
||||||
|
def error(e: => String): Unit = s.log.debug(e)
|
||||||
|
def buffer[T](f: => T): T = f
|
||||||
|
}
|
||||||
|
val exitCode = Process(List("make", "clean", "html", "pdf"), dir) ! logger
|
||||||
|
if (exitCode != 0) sys.error("Failed to build docs.")
|
||||||
|
s.log.info("Creating reStructuredText documentation successful.")
|
||||||
|
IO.copyDirectory(dir / "_build" / "html", target)
|
||||||
|
IO.copyFile(dir / "_build" / "latex" / "Akka.pdf", target / "Akka.pdf")
|
||||||
|
target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package akka
|
package akka
|
||||||
|
|
||||||
import sbt._
|
import sbt._
|
||||||
import Keys._
|
import sbt.Keys._
|
||||||
import Project.Initialize
|
import sbt.Project.Initialize
|
||||||
|
|
||||||
object Unidoc {
|
object Unidoc {
|
||||||
val unidocDirectory = SettingKey[File]("unidoc-directory")
|
val unidocDirectory = SettingKey[File]("unidoc-directory")
|
||||||
|
|
|
||||||
85
project/scripts/find-replace
Executable file
85
project/scripts/find-replace
Executable file
|
|
@ -0,0 +1,85 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Find and replace across all source files.
|
||||||
|
# This script will be called as part of the release script.
|
||||||
|
|
||||||
|
# get the source location for this script; handles symlinks
|
||||||
|
function get_script_path {
|
||||||
|
local source="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "${source}" ] ; do
|
||||||
|
source="$(readlink "${source}")";
|
||||||
|
done
|
||||||
|
echo ${source}
|
||||||
|
}
|
||||||
|
|
||||||
|
# path, name, and dir for this script
|
||||||
|
declare -r script_path=$(get_script_path)
|
||||||
|
declare -r script_name=$(basename "${script_path}")
|
||||||
|
declare -r script_dir="$(cd -P "$(dirname "${script_path}")" && pwd)"
|
||||||
|
|
||||||
|
# print usage info
|
||||||
|
function usage {
|
||||||
|
echo "Usage: ${script_name} find_expr replace_expr"
|
||||||
|
}
|
||||||
|
|
||||||
|
function echolog {
|
||||||
|
echo "[${script_name}] $@"
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -r find_expr=$1
|
||||||
|
declare -r replace_expr=$2
|
||||||
|
|
||||||
|
if [ -z "$find_expr" ]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echolog "$find_expr --> $replace_expr"
|
||||||
|
|
||||||
|
# exclude directories from search
|
||||||
|
|
||||||
|
declare exclude_dirs=".git dist deploy embedded-repo lib_managed project/boot project/scripts src_managed target"
|
||||||
|
|
||||||
|
echolog "excluding directories: $exclude_dirs"
|
||||||
|
|
||||||
|
exclude_opts="\("
|
||||||
|
op="-path"
|
||||||
|
for dir in $exclude_dirs; do
|
||||||
|
exclude_opts="${exclude_opts} ${op} '*/${dir}/*'"
|
||||||
|
op="-or -path"
|
||||||
|
done
|
||||||
|
exclude_opts="${exclude_opts} \) -prune -o"
|
||||||
|
|
||||||
|
# replace in files
|
||||||
|
|
||||||
|
search="find . ${exclude_opts} -type f -print0 | xargs -0 grep -Il \"$find_expr\""
|
||||||
|
|
||||||
|
files=$(eval "$search")
|
||||||
|
|
||||||
|
simple_diff="diff --old-line-format='[$script_name] - %l
|
||||||
|
' --new-line-format='[$script_name] + %l
|
||||||
|
' --changed-group-format='%<%>' --unchanged-group-format=''"
|
||||||
|
|
||||||
|
for file in $files; do
|
||||||
|
echolog $file
|
||||||
|
# escape / for sed
|
||||||
|
sedfind=$(echo $find_expr | sed 's/\//\\\//g')
|
||||||
|
sedreplace=$(echo $replace_expr | sed 's/\//\\\//g')
|
||||||
|
sed -i '.sed' "s/${sedfind}/${sedreplace}/g" $file
|
||||||
|
eval "$simple_diff $file.sed $file"
|
||||||
|
rm -f $file.sed
|
||||||
|
done
|
||||||
|
|
||||||
|
# replace in file names
|
||||||
|
|
||||||
|
search="find . ${exclude_opts} -type f -name \"*${find_expr}*\" -print"
|
||||||
|
|
||||||
|
files=$(eval "$search")
|
||||||
|
|
||||||
|
for file in $files; do
|
||||||
|
dir=$(dirname $file)
|
||||||
|
name=$(basename $file)
|
||||||
|
newname=$(echo $name | sed "s/${find_expr}/${replace_expr}/g")
|
||||||
|
echolog "$file --> $newname"
|
||||||
|
mv $file $dir/$newname
|
||||||
|
done
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Find and replace across all source files.
|
|
||||||
#
|
|
||||||
# Example usage:
|
|
||||||
#
|
|
||||||
# sh project/scripts/find-replace.sh 1.1-SNAPSHOT 1.1-RC1
|
|
||||||
#
|
|
||||||
# This script will be called as part of the sbt release script.
|
|
||||||
|
|
||||||
FIND=$1
|
|
||||||
REPLACE=$2
|
|
||||||
|
|
||||||
if [ -z "$FIND" ]; then
|
|
||||||
echo "Usage: find-replace.sh FIND REPLACE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "Find and replace: $FIND --> $REPLACE"
|
|
||||||
|
|
||||||
|
|
||||||
# Exclude directories from search
|
|
||||||
|
|
||||||
excludedirs=".git dist deploy embedded-repo lib_managed project/boot project/scripts src_managed target"
|
|
||||||
|
|
||||||
echo "Excluding directories: $excludedirs"
|
|
||||||
|
|
||||||
excludeopts="\("
|
|
||||||
op="-path"
|
|
||||||
for dir in $excludedirs; do
|
|
||||||
excludeopts="${excludeopts} ${op} '*/${dir}/*'"
|
|
||||||
op="-or -path"
|
|
||||||
done
|
|
||||||
excludeopts="${excludeopts} \) -prune -o"
|
|
||||||
|
|
||||||
|
|
||||||
# Replace in files
|
|
||||||
|
|
||||||
search="find . ${excludeopts} -type f -print0 | xargs -0 grep -Il \"${FIND}\""
|
|
||||||
|
|
||||||
echo $search
|
|
||||||
echo
|
|
||||||
|
|
||||||
files=$(eval "$search")
|
|
||||||
|
|
||||||
simplediff="diff --old-line-format='- %l
|
|
||||||
' --new-line-format='+ %l
|
|
||||||
' --changed-group-format='%<%>' --unchanged-group-format=''"
|
|
||||||
|
|
||||||
for file in $files; do
|
|
||||||
echo
|
|
||||||
echo $file
|
|
||||||
# escape / for sed
|
|
||||||
sedfind=$(echo $FIND | sed 's/\//\\\//g')
|
|
||||||
sedreplace=$(echo $REPLACE | sed 's/\//\\\//g')
|
|
||||||
sed -i '.sed' "s/${sedfind}/${sedreplace}/g" $file
|
|
||||||
eval "$simplediff $file.sed $file"
|
|
||||||
rm -f $file.sed
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
|
|
||||||
# Replace in file names
|
|
||||||
|
|
||||||
search="find . ${excludeopts} -type f -name \"*${FIND}*\" -print"
|
|
||||||
|
|
||||||
echo $search
|
|
||||||
echo
|
|
||||||
|
|
||||||
files=$(eval "$search")
|
|
||||||
|
|
||||||
for file in $files; do
|
|
||||||
dir=$(dirname $file)
|
|
||||||
name=$(basename $file)
|
|
||||||
newname=$(echo $name | sed "s/${FIND}/${REPLACE}/g")
|
|
||||||
echo "$file --> $newname"
|
|
||||||
mv $file $dir/$newname
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
VERSION=$1
|
|
||||||
|
|
||||||
if [ -z "$VERSION" ]; then
|
|
||||||
echo "Usage: push-release.sh VERSION"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
source ~/.akka-release
|
|
||||||
|
|
||||||
if [ -z "$AKKA_RELEASE_SERVER" ]; then
|
|
||||||
echo "Need AKKA_RELEASE_SERVER to be specified"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$AKKA_RELEASE_PATH" ]; then
|
|
||||||
echo "Need AKKA_RELEASE_PATH to be specified"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ref=$(git symbolic-ref HEAD 2> /dev/null)
|
|
||||||
branch=${ref#refs/heads/}
|
|
||||||
|
|
||||||
git push origin $branch
|
|
||||||
git push origin --tags
|
|
||||||
|
|
||||||
release="target/release/${VERSION}"
|
|
||||||
tmp="/tmp/akka-release-${VERSION}"
|
|
||||||
|
|
||||||
rsync -avz ${release}/ ${AKKA_RELEASE_SERVER}:${tmp}/
|
|
||||||
echo "Verify sudo on $AKKA_RELEASE_SERVER"
|
|
||||||
ssh -t ${AKKA_RELEASE_SERVER} sudo -v
|
|
||||||
ssh -t ${AKKA_RELEASE_SERVER} sudo rsync -rpt ${tmp}/ ${AKKA_RELEASE_PATH}
|
|
||||||
ssh -t ${AKKA_RELEASE_SERVER} rm -rf ${tmp}
|
|
||||||
244
project/scripts/release
Normal file → Executable file
244
project/scripts/release
Normal file → Executable file
|
|
@ -1,10 +1,234 @@
|
||||||
sh git checkout -b releasing-{{release.arg1}}
|
#!/usr/bin/env bash
|
||||||
set akka.release true
|
#
|
||||||
clean
|
# Release script for Akka.
|
||||||
script find-replace.sh {{project.version}} {{release.arg1}}
|
|
||||||
script find-replace.sh //[[:space:]]*release:[[:space:]]*
|
# defaults
|
||||||
reload
|
declare -r default_server="akka.io"
|
||||||
build-release
|
declare -r default_path="/akka/www"
|
||||||
sh git add .
|
|
||||||
sh git commit -am 'Update version for release {{project.version}}'
|
# settings
|
||||||
sh git tag -m 'Version {{project.version}}' v{{project.version}}
|
declare -r release_dir="target/release"
|
||||||
|
declare release_server=${default_server}
|
||||||
|
declare release_path=${default_path}
|
||||||
|
|
||||||
|
# flags
|
||||||
|
unset run_tests
|
||||||
|
|
||||||
|
# get the source location for this script; handles symlinks
|
||||||
|
function get_script_path {
|
||||||
|
local source="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "${source}" ] ; do
|
||||||
|
source="$(readlink "${source}")";
|
||||||
|
done
|
||||||
|
echo ${source}
|
||||||
|
}
|
||||||
|
|
||||||
|
# path, name, and dir for this script
|
||||||
|
declare -r script_path=$(get_script_path)
|
||||||
|
declare -r script_name=$(basename "${script_path}")
|
||||||
|
declare -r script_dir="$(cd -P "$(dirname "${script_path}")" && pwd)"
|
||||||
|
|
||||||
|
# print usage info
|
||||||
|
function usage {
|
||||||
|
cat <<EOM
|
||||||
|
Usage: ${script_name} [options] VERSION
|
||||||
|
-h | --help Print this usage message
|
||||||
|
-t | --run-tests Run all tests before releasing
|
||||||
|
-s | --server SERVER Set the release server (default ${default_server})
|
||||||
|
-p | --path PATH Set the path on the release server (default ${default_path})
|
||||||
|
EOM
|
||||||
|
}
|
||||||
|
|
||||||
|
# echo a log message
|
||||||
|
function echolog {
|
||||||
|
echo "[${script_name}] $@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# echo an error message
|
||||||
|
function echoerr {
|
||||||
|
echo "[${script_name}] $@" 1>&2
|
||||||
|
}
|
||||||
|
|
||||||
|
# fail the script with an error message
|
||||||
|
function fail {
|
||||||
|
echoerr "$@"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# process options and set flags
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h | --help ) usage; exit 1 ;;
|
||||||
|
-t | --run-tests ) run_tests=true; shift ;;
|
||||||
|
-s | --server ) release_server=$2; shift 2 ;;
|
||||||
|
-p | --path ) release_path=$2; shift 2 ;;
|
||||||
|
* ) break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $# != "1" ]; then
|
||||||
|
usage
|
||||||
|
fail "A release version must be specified"
|
||||||
|
fi
|
||||||
|
|
||||||
|
declare -r version=$1
|
||||||
|
declare -r publish_path="${release_server}:${release_path}"
|
||||||
|
|
||||||
|
# check for a git command
|
||||||
|
type -P git &> /dev/null || fail "git command not found"
|
||||||
|
|
||||||
|
# check for an sbt command
|
||||||
|
type -P sbt &> /dev/null || fail "sbt command not found"
|
||||||
|
|
||||||
|
# get the current git branch
|
||||||
|
function get_current_branch {
|
||||||
|
local ref=$(git symbolic-ref HEAD 2> /dev/null)
|
||||||
|
local branch=${ref#refs/heads/}
|
||||||
|
echo "${branch}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# get the current project version from sbt
|
||||||
|
# a little messy as the ansi escape codes are included
|
||||||
|
function get_current_version {
|
||||||
|
local result=$(sbt version | tail -1 | cut -f2)
|
||||||
|
# remove ansi escape code from end
|
||||||
|
local code0=$(echo -e "\033[0m")
|
||||||
|
echo ${result%$code0}
|
||||||
|
}
|
||||||
|
|
||||||
|
# store the current git branch for cleaning up
|
||||||
|
declare -r initial_branch=$(get_current_branch)
|
||||||
|
|
||||||
|
# check we have an initial branch
|
||||||
|
[[ "${initial_branch}" ]] || fail "Not on a git branch"
|
||||||
|
|
||||||
|
# check that we have a clean status
|
||||||
|
[[ -z "$(git status --porcelain)" ]] || {
|
||||||
|
git status
|
||||||
|
fail "There are uncommitted changes - please commit before releasing"
|
||||||
|
}
|
||||||
|
|
||||||
|
# the branch we'll release on
|
||||||
|
declare -r release_branch="releasing-${version}"
|
||||||
|
|
||||||
|
# try to run a cleanup command - these shouldn't actually fail
|
||||||
|
function safely {
|
||||||
|
"$@" || fail "Failed to clean up release - please check current state"
|
||||||
|
}
|
||||||
|
|
||||||
|
# perform a clean up when a failure has occurred
|
||||||
|
function git_cleanup {
|
||||||
|
echoerr "Cleaning up..."
|
||||||
|
local branch=$(get_current_branch)
|
||||||
|
safely git reset --hard
|
||||||
|
safely git clean -f
|
||||||
|
if [ "${branch}" == "${release_branch}" ]; then
|
||||||
|
safely git checkout ${initial_branch}
|
||||||
|
safely git branch -d ${release_branch}
|
||||||
|
local tags=$(git tag -l)
|
||||||
|
[[ "${tags}" == *v${version}* ]] && safely git tag -d v${version}
|
||||||
|
fi
|
||||||
|
echoerr "Cleaned up failed release"
|
||||||
|
}
|
||||||
|
|
||||||
|
# clean up and fail the script with an error message
|
||||||
|
function bail_out {
|
||||||
|
echoerr "Bailing out!"
|
||||||
|
git_cleanup
|
||||||
|
fail "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# bail out for signals
|
||||||
|
function signal_bail_out {
|
||||||
|
echoerr "Interrupted by signal"
|
||||||
|
bail_out "Received signal to stop release"
|
||||||
|
}
|
||||||
|
|
||||||
|
# bail out on signals
|
||||||
|
trap signal_bail_out SIGHUP SIGINT SIGTERM
|
||||||
|
|
||||||
|
# try to run a command or otherwise bail out
|
||||||
|
function try {
|
||||||
|
"$@" || bail_out "Failed to create release"
|
||||||
|
}
|
||||||
|
|
||||||
|
echolog "Creating release ${version} ..."
|
||||||
|
echolog "Publishing to ${publish_path}"
|
||||||
|
[[ $run_tests ]] && echolog "All tests will be run"
|
||||||
|
|
||||||
|
# try ssh'ing to the release server
|
||||||
|
echolog "Checking ssh connection to ${release_server}"
|
||||||
|
try ssh -t ${release_server} echo "Successfully contacted release server."
|
||||||
|
|
||||||
|
echolog "Getting current project version from sbt..."
|
||||||
|
declare -r current_version=$(get_current_version)
|
||||||
|
echolog "Current version is ${current_version}"
|
||||||
|
|
||||||
|
# check out a release branch
|
||||||
|
try git checkout -b ${release_branch}
|
||||||
|
|
||||||
|
# find and replace the version
|
||||||
|
try ${script_dir}/find-replace ${current_version} ${version}
|
||||||
|
|
||||||
|
# start clean
|
||||||
|
try sbt clean
|
||||||
|
|
||||||
|
# run the tests if specified
|
||||||
|
if [ $run_tests ]; then
|
||||||
|
echolog "Running all tests..."
|
||||||
|
try sbt test
|
||||||
|
echolog "All tests are green"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# build the release
|
||||||
|
echolog "Building the release..."
|
||||||
|
try sbt build-release
|
||||||
|
echolog "Successfully created local release"
|
||||||
|
|
||||||
|
# commit and tag this release
|
||||||
|
echolog "Committing and tagging..."
|
||||||
|
try git add .
|
||||||
|
try git commit -am "Update version for release ${version}"
|
||||||
|
try git tag -m "Version ${version}" v${version}
|
||||||
|
|
||||||
|
# the point of no return... we're now pushing out to servers
|
||||||
|
|
||||||
|
# use a special failure from now on
|
||||||
|
function arrgh {
|
||||||
|
cat 1>&2 <<EOM
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
|
||||||
|
Release failed while pushing to servers!
|
||||||
|
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
EOM
|
||||||
|
fail "Could not complete release - please check current state"
|
||||||
|
}
|
||||||
|
|
||||||
|
# try running a pushing command or otherwise fail
|
||||||
|
function important {
|
||||||
|
"$@" || arrgh
|
||||||
|
}
|
||||||
|
|
||||||
|
# new interrupted bail out for signals
|
||||||
|
function arrgh_interrupt {
|
||||||
|
echoerr "Interrupted by signal"
|
||||||
|
arrgh
|
||||||
|
}
|
||||||
|
|
||||||
|
# new exit on signals
|
||||||
|
trap arrgh_interrupt SIGHUP SIGINT SIGTERM
|
||||||
|
|
||||||
|
# push the commits and tags to git origin
|
||||||
|
echolog "Pushing to git origin..."
|
||||||
|
important git push origin ${release_branch}
|
||||||
|
important git push origin --tags
|
||||||
|
|
||||||
|
# push the release to the server
|
||||||
|
echolog "Pushing ${release_dir} to ${publish_path} ..."
|
||||||
|
important rsync -rlpvz --chmod=Dg+ws,Fg+w ${release_dir}/ ${publish_path}/
|
||||||
|
|
||||||
|
echolog "Switching back to initial branch"
|
||||||
|
git checkout ${initial_branch}
|
||||||
|
|
||||||
|
echolog "Successfully created release ${version}"
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
set akka.release true
|
|
||||||
clean
|
|
||||||
clean-lib
|
|
||||||
script find-replace.sh {{project.version}} {{test-release.arg1}}
|
|
||||||
script find-replace.sh //[[:space:]]*release:[[:space:]]*
|
|
||||||
reload
|
|
||||||
update
|
|
||||||
test-compile
|
|
||||||
test
|
|
||||||
build-release
|
|
||||||
sh git reset --hard
|
|
||||||
sh git clean -f
|
|
||||||
reload
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue