This repository has been archived by the owner on Jul 22, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
unsafePublishModules.sh
413 lines (311 loc) · 11 KB
/
unsafePublishModules.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
#!/bin/bash
#It is called unsafe so most people stay away from this
#But this script MAY TURN OUT TO BE safe to use if you are trying
#to publish all Lift modules to sonatype
# Usage: sh unsafePublishModules.sh [modules-step-1.txt]
# ...then follow the prompts.
## This scripts runs on mac's bash terminal
set -o errexit
set -o nounset
BUILDLOG=/tmp/Liftmodules-do-release-`date "+%Y%m%d-%H%M%S"`.log
date > $BUILDLOG
PUSH_SCRIPT=/tmp/LiftModules-push-`date "+%Y%m%d-%H%M%S"`.sh
SBT_OPTS="-Dsbt.log.noformat=true -Dfile.encoding=utf8 -XX:MaxPermSize=384m -Xmx768M -Xss2M -XX:+CMSClassUnloadingEnabled"
# This script is an attempt to automate the Lift Module release process
# based on the Lift script. The process is:
# For each module:
# 1. Checkout the module
# 2. Figure out the module version number
# 3. Create a branch based on the Lift version number and the module version number
# 4. Modify the Lift and module version numbers in the module's build.sbt
# 5. Try to build, fail on error.
# 6. Commit the change, log the push command to run.
# 7. +publish
#
SCRIPTVERSION=3.0
SCRIPT_NAME="${PWD##*/}"
SCRIPT_DIR="${PWD}"
SBT_JAR="$SCRIPT_DIR/sbt-launch-0.12.jar"
# There may be a better way to scope the change to IFS that happens in this script
# but for now, I'm saving the default value and restoring it after each change.
DEFAULT_IFS=$IFS
# if the script was started from the base directory, then the
# expansion returns a period
if test "$SCRIPT_DIR" == "." ; then
SCRIPT_DIR="$PWD"
# if the script was not called with an absolute path, then we need to add the
# current working directory to the relative path of the script
elif test "${SCRIPT_DIR:0:1}" != "/" ; then
SCRIPT_DIR="$PWD/$SCRIPT_DIR"
fi
##### Utility functions (break these out into an include?) #####
# Basically yes/no confirmation with customized messages
# Usage: confirm "prompt"
# Returns 0 for yes, 1 for no
function confirm {
while read -p "$1 [yes/no] " CONFIRM; do
case "`echo $CONFIRM | tr [:upper:] [:lower:]`" in
yes)
return 0
;;
no)
return 1
;;
*)
echo "Please enter yes or no"
;;
esac
done
}
function debug {
echo $@
echo -n ""
}
function die {
echo $@
exit 1
}
# figure out project folder name from git clone URL
# and return it as $PROJNAME
function projname {
gitname=$(basename $1) # git://github.com/liftmodules/paypal.git -> "paypal.git"
PROJNAME=${gitname%.*} # "paypal.git" -> "paypal"
return 0
}
function isSnapshot {
if [[ "$1" =~ .*-SNAPSHOT$ ]]; then
return 0; #true
fi
return 1; #false
}
function isNotSnapshot {
if [[ "$1" =~ .*-SNAPSHOT$ ]]; then
return 1;
fi
return 0;
}
# "2.5-RC1" => 2
# "3.0-SNAPSHOT" => 3
function liftSeries {
return ${1:0:1}
}
# Look in the current build.sbt for:
# version := "1.2-SNAPSHOT"
# and return the version number (less any snapshot) in $MODULE_VERSION
function readModuleVersion {
REASON=""
line=`grep 'version :=' build.sbt`
if [ $? -ne 0 ] ; then die "Unable to find version in build.sbt" ; fi
if [[ "$line" =~ \"-?([^-]+)(-SNAPSHOT)?\" ]]
then
RAW_MOD_VERSION=${BASH_REMATCH[1]}
MODULE_VERSION=${RAW_MOD_VERSION//[^0-9.]/}
return 0
else
REASON="Failed to pick out version from: $line"
return 1
fi
}
# Modify build.sbt to update the module version number and the Lift version number
function updateBuild {
REASON=""
LIFT_VER=$1
MOD_VER=$2
# TODO: Replace with SBT session saving
sed -i.bak "s/liftVersion ?? \"[^\"]*\"/liftVersion ?? \"$LIFT_VER\"/g" build.sbt
if [ $? -ne 0 ] ; then
REASON="Failed to update Lift version"
return 1
fi
rm build.sbt.bak
sed -i.bak "s/^version := .*$/version := \"$MOD_VER\"/g" build.sbt
if [ $? -ne 0 ] ; then
REASON="Failed to update Module version"
return 1
fi
rm build.sbt.bak
liftSeries $LIFT_VER
if [ "$?" -eq 3 ]; then
sed -i.bak "s/^crossScalaVersions.*$/crossScalaVersions := Seq(\"2.10.0\")/g" build.sbt
if [ $? -ne 0 ] ; then
REASON="Failed to update Module crossbuilds"
return 1
fi
else
sed -i.bak "s/^crossScalaVersions.*$/crossScalaVersions := Seq(\"2.10.0\", \"2.9.2\", \"2.9.1-1\", \"2.9.1\")/g" build.sbt
if [ $? -ne 0 ] ; then
REASON="Failed to update Module crossbuilds"
return 1
fi
fi
rm build.sbt.bak
return 0
}
##### End Utility Functions #####
moduleFile="$SCRIPT_DIR/modules-step-1.txt"
if [ $# -eq 1 ]; then
moduleFile=$1
fi
echo "*********************************************************************"
printf "* Lift Module Release build script version %-24s *\n" "$SCRIPTVERSION"
printf "*********************************************************************\n\n"
echo "SCRIPT_DIR is ${SCRIPT_DIR}"
echo "Module list file: ${moduleFile}"
echo "Build output logged to $BUILDLOG\n"
if [ ! -e $moduleFile ] ; then
die "Module list file missing: ${moduleFile}"
fi
# Any Module set up could go here
# CouchDB will blow up with HTTP proxy set because it doesn't correctly interpret the return codes
#set +o nounset
#if [ ! -z "${http_proxy}" -o ! -z "${HTTP_PROXY}" ]; then
# echo -e "CouchDB tests will fail with http_proxy set! Please unset and re-run.\n"
# exit
#fi
#set -o nounset
if [ ! -e $HOME/.sbt/plugins/gpg.sbt ]; then
echo "WARNING: $HOME/.sbt/plugins/gpg.sbt not found"
echo "The GPG plugin is required to publish to Sonatype, see:"
echo "https://www.assembla.com/spaces/liftweb/wiki/Releasing_the_modules"
echo " "
fi
cloneModules() {
echo "-----------------------------------------------------------------"
echo "Starting PHASE 1: The clone of the modules, branch, modify build"
echo "-----------------------------------------------------------------"
mkdir -v $STAGING_DIR
if [ $? -ne 0 ] ; then die "Failed to mkdir" ; fi
for ml in "${MODULES[@]}"
do
# Split the line on a comma and the first value is the repo:
IFS=, MODULE_INFO=( $ml )
IFS=$DEFAULT_IFS
m=${MODULE_INFO[0]}
projname "$m" || die "Odd git project name: cannot figure out directory name. Help."
echo "Cloning $m -> $PROJNAME"
cd $STAGING_DIR
git clone $m >> ${BUILDLOG}
if [ $? -ne 0 ] ; then die "Failed to clone $m" ; fi
cd $PROJNAME
readModuleVersion || die "Failed to locate module version number: $REASON"
echo "Version of $PROJNAME in Git: $MODULE_VERSION"
if [ ${#MODULE_INFO[@]} -ne 1 ] ; then
MODULE_VERSION=${MODULE_INFO[1]}
echo "Requested $PROJNAME version: $MODULE_VERSION"
fi
if isSnapshot $RELEASE_VERSION ; then
echo "Forcing to SNAPSHOT build because Lift version is a SNAPSHOT: $MODULE_VERSION-SNAPSHOT"
updateBuild $RELEASE_VERSION $MODULE_VERSION-SNAPSHOT || die "Unable to update build.sbt because $REASON"
else
git checkout -b $RELEASE_VERSION-$MODULE_VERSION
if [ $? -ne 0 ] ; then die "Failed to branch as $RELEASE_VERSION-$MODULE_VERSION" ; fi
updateBuild $RELEASE_VERSION $MODULE_VERSION || die "Unable to update build.sbt because $REASON"
git commit -v -a -m "Prepare for Lift ${RELEASE_VERSION} release" >> ${BUILDLOG} || die "Could not commit project version change!"
git tag ${RELEASE_VERSION}-${MODULE_VERSION}-release >> ${BUILDLOG} || echo "WARNING: Could not tag release!"
fi
cd $SCRIPT_DIR
echo " "
done
}
buildAndTest() {
echo " "
echo "-----------------------------------------------------------------"
echo "Starting PHASE 2: Build and test"
echo "-----------------------------------------------------------------"
echo " "
echo "If you want to follow along, tail -f $BUILDLOG"
echo " "
echo "Phase 2" >> ${BUILDLOG}
java -version 2>> ${BUILDLOG}
for ml in "${MODULES[@]}"
do
IFS=, MODULE_INFO=( $ml )
IFS=$DEFAULT_IFS
m=${MODULE_INFO[0]}
projname "$m" || die "Odd git project name, cannot work out directory this time."
cd $STAGING_DIR
cd $PROJNAME
echo "$PROJNAME: packaging and testing"
set +o errexit
pwd >> ${BUILDLOG}
echo "java $SBT_OPTS -jar $SBT_JAR +package +test" >> ${BUILDLOG}
java $SBT_OPTS -jar $SBT_JAR +package +test >> ${BUILDLOG}
if [ $? -ne 0 ] ; then die "Build or test failure in $PROJNAME - see $BUILDLOG for details" ; fi
set -o errexit
cd $SCRIPT_DIR
done
}
publish() {
echo " "
echo "-----------------------------------------------------------------"
echo "Starting PHASE 3: Publish"
echo "-----------------------------------------------------------------"
echo " "
echo "During this phase you will be asked to enter your PGP passphrase"
echo "i.e., watch this console and response to prompts."
echo " "
confirm "Modules all appear OK. Proceed to publish step?" || die "Canceling release build!"
for ml in "${MODULES[@]}"
do
IFS=, MODULE_INFO=( $ml )
IFS=$DEFAULT_IFS
m=${MODULE_INFO[0]}
projname "$m" || die "Worked twice, but now cannot work out directory."
cd $STAGING_DIR
cd $PROJNAME
echo "$PROJNAME: publishing..."
java $SBT_OPTS -jar $SBT_JAR +publish
echo "cd $STAGING_DIR/$PROJNAME" >> $PUSH_SCRIPT
echo "git push --tags" >> $PUSH_SCRIPT
cd $SCRIPT_DIR
done
echo "Release build complete `date`" >> ${BUILDLOG}
echo " "
echo "RELEASE BUILD COMPLETE."
if isNotSnapshot $RELEASE_VERSION ; then
echo "Next: 1. Visit https://oss.sonatype.org/index.html to close and release"
echo " 2. To push tags, run: sh $PUSH_SCRIPT"
fi
}
# -- MAIN -------------------------------------------------------------------------------
read -p "Please enter the Lift version of the release: " RELEASE_VERSION
if isSnapshot $RELEASE_VERSION ; then
echo " "
echo "Snapshot build detected: will skip tagging, signing not required."
echo " "
else
# Sanity check on the release version
if ! echo $RELEASE_VERSION | egrep -x '[0-9]+\.[0-9]+(-(M|RC)[0-9]+)?' > /dev/null; then
confirm "$RELEASE_VERSION does not appear to be a valid release version. Are you sure?" ||
die "Canceling release build!"
fi
fi
STAGING_DIR="$SCRIPT_DIR/staging"
MODULES=( `cat "$moduleFile" `)
echo "This is what's about to happen:"
echo "1. The following modules will be checked out to a staging directory:"
for m in "${MODULES[@]}"
do
echo " $m"
done
echo "2. A branch will be created for each module and configured for this release (skipped for snapshots)"
echo "3. Each module will be built"
echo "4. On success, the module will be published".
echo " "
confirm "Continue?" || die "Canceling release build."
if [ -e $STAGING_DIR ] ; then
set +o errexit
confirm "$STAGING_DIR exists. Happy to remove it? (no to use existing directory to publish)"
freshBuild=$?
set -o errexit
if [ $freshBuild -eq 0 ] ; then
rm -rf $STAGING_DIR
cloneModules
buildAndTest
fi
else
# No staging directory
cloneModules
buildAndTest
fi
publish