Fix make-array transforms.
[sbcl.git] / release.sh
1 #!/bin/bash
2
3 # Sourceforge username
4 SFUSER=${SFUSER:-$USER}
5
6 set -ex
7
8 ## Parse command line arguments
9
10 usage () {
11     if ! [ -z "$1" ]
12     then
13         echo $1
14     fi
15     cat <<EOF
16
17 usage: $0 [-s] VERSION-NUMBER [REV]
18
19   This script frobs NEWS, makes a "release" commit + tag of the
20   repository in \$PWD/release.sbcl .
21
22   It then clones the repository to a new clean directory and does the
23   following:
24   - Builds source tarball
25   - Builds a SBCL for self-build
26   - Builds x86-64 binaries
27   - Uploads binaries
28   - Pushes the repository
29   - Builds and uploads the documentation
30
31   If -s is given, then use the gpg-sign mechanism of "git tag". You
32   will need to have your gpg secret key handy.
33
34   if REV is given, it is the git revision to build into a release.
35   Default is origin/master.
36
37   ENVIRONMENT:
38
39   SFUSER: Sourceforge username. Defaults to \$USER
40   SBCL_RELEASE_DIR: Absolute path to directory containing all the build
41     artifacts. If not defined, a new build directory is created in \$PWD.
42
43 EOF
44     exit 1
45 }
46
47 if [ "-s" = "$1" ] || [ "--sign" = "$1" ]
48 then
49     sign="-s"; shift
50 else
51     sign=""
52 fi
53
54 ## Verify version number
55
56 if [ -z "$1" ]
57 then
58     usage "No version number."
59 else
60     VERSION=$1; shift
61     echo $VERSION | perl -pe 'die "Invalid version number: $_\n" if !/^\d+\.\d+\.\d+$/'
62 fi
63
64 if [ -z "$1" ]
65 then
66     rev=origin/master
67 else
68     rev=$1; shift
69     type=$(git cat-file -t "$rev" 2> /dev/null || echo "unknown")
70     if ([ "tag" != "$type" ] && [ "commit" != "$type" ])
71     then
72         usage "$rev is $type, not a tag or a commit."
73     fi
74 fi
75
76 if ! [ -z "$@" ]
77 then
78     usage "Extra command-line arguments: $@"
79 fi
80
81 SBCL_RELEASE_DIR=${SBCL_RELEASE_DIR:-$(mktemp -d $PWD/sbcl-release-dir-$(date +%Y%m%d)-XXXXXXXXX)}
82 SBCL_DIR=$SBCL_RELEASE_DIR/sbcl-$VERSION
83 GIT_DIR=$PWD/release.sbcl
84 LOGFILE=$SBCL_RELEASE_DIR/log.txt
85
86 ## Frob the git repository, and clone the repo to a clean build directory.
87
88 if [ ! -d $SBCL_DIR ]; then
89   cd $GIT_DIR
90
91   sbcl_directory="$(cd "$(dirname $0)"; pwd)"
92
93   branch_name="release-$(date '+%s')"
94   original_branch="$(git describe --all --contains HEAD)"
95
96   echo "Checking that the tree is clean."
97   if ! [ $(git status --porcelain | wc -l) = 0 ]
98   then
99       echo "There are uncommitted / unpushed changes in this checkout!"
100       git status
101       exit 1
102   fi
103
104   ## Perform the necessary changes to the NEWS file:
105
106   echo "Munging NEWS"
107   sed -i.orig "/^changes relative to sbcl-.*:/ s/changes/changes in sbcl-$VERSION/ " NEWS
108   rm -f NEWS.orig
109   if ! grep "^changes in sbcl-$VERSION relative to" NEWS > /dev/null
110   then
111       echo "NEWS munging failed!"
112       exit 1
113   fi
114
115   ## Commit
116
117   cd "$sbcl_directory"
118
119   echo "Committing release version."
120   git add NEWS
121   git commit -m "$VERSION: will be tagged as \"sbcl-$VERSION\""
122
123   ## Make release notes
124
125   if [ ! -f $SBCL_RELEASE_DIR/sbcl-$VERSION-release-notes.txt ]; then
126     awk "BEGIN { state = 0 }
127      /^changes in sbcl-/ { state = 0 } 
128      /^changes in sbcl-$VERSION/ { state = 1 }
129      { if(state == 1) print \$0 }" < $GIT_DIR/NEWS > $SBCL_RELEASE_DIR/sbcl-$VERSION-release-notes.txt
130   fi
131
132   ## Tag
133
134   tag="sbcl-$VERSION"
135   echo "Tagging as $tag"
136   git tag $sign -F $SBCL_RELEASE_DIR/sbcl-$VERSION-release-notes.txt "$tag"
137
138   git clone $GIT_DIR $SBCL_DIR
139 fi
140
141 ## Make the source tarball.
142
143 if [ ! \( -f $SBCL_RELEASE_DIR/sbcl-$VERSION-source.tar -o -f $SBCL_RELEASE_DIR/sbcl-$VERSION-source.tar.bz2 \) ]; then
144   cd $SBCL_DIR
145   (. $SBCL_DIR/generate-version.sh; generate_version)
146   mkdir -p CVS
147   sh ./distclean.sh
148   rm -rf .git
149
150   cd $SBCL_RELEASE_DIR
151   sh sbcl-$VERSION/source-distribution.sh sbcl-$VERSION
152
153   mv $SBCL_DIR $SBCL_DIR.git
154
155   tar xvf sbcl-$VERSION-source.tar
156 fi
157
158 ## Build x86-64 binary for bootstrap.
159
160 if [ ! -d $SBCL_RELEASE_DIR/bin ]; then
161   cd $SBCL_DIR
162   nice -20 ./make.sh >$LOGFILE 2>&1
163
164   cd tests
165   nice -20 sh ./run-tests.sh >>$LOGFILE 2>&1
166   mkdir -p $SBCL_RELEASE_DIR/bin
167   cp $SBCL_DIR/src/runtime/sbcl $SBCL_RELEASE_DIR/bin/sbcl
168   cp $SBCL_DIR/output/sbcl.core $SBCL_RELEASE_DIR/bin/sbcl.core
169 fi
170
171 ## Build x86-64 release binary.
172
173 if [ ! -d $SBCL_RELEASE_DIR/sbcl-$VERSION-x86-64-linux ]; then
174   cd $SBCL_DIR
175   sh clean.sh
176   nice -20 ./make.sh "$SBCL_RELEASE_DIR/bin/sbcl --core $SBCL_RELEASE_DIR/bin/sbcl.core --no-userinit" >> $LOGFILE 2>&1
177   cd doc && sh ./make-doc.sh
178   cd $SBCL_RELEASE_DIR
179
180   ln -s $SBCL_DIR $SBCL_RELEASE_DIR/sbcl-$VERSION-x86-64-linux
181   sh $SBCL_DIR/binary-distribution.sh sbcl-$VERSION-x86-64-linux
182   sh $SBCL_DIR/html-distribution.sh sbcl-$VERSION
183 fi
184
185 ## Build x86 release binary.
186
187 #if [ ! -d $SBCL_RELEASE_DIR/sbcl-$VERSION-x86-linux ]; then
188 #  cd $SBCL_DIR
189 #  sh clean.sh
190 #  export SBCL_ARCH=x86
191 #  export PATH=/scratch/src/release/x86-gcc-wrapper:$PATH
192 #  nice -20 ./make.sh "$SBCL_RELEASE_DIR/bin/sbcl --core $SBCL_RELEASE_DIR/bin/s#bcl.core --no-userinit" >> $LOGFILE 2>&1
193 #  cd tests
194 #  nice -20 sh ./run-tests.sh >>$LOGFILE 2>&
195
196 #  cd $SBCL_RELEASE_DIR
197 #  ln -s $SBCL_DIR $SBCL_RELEASE_DIR/sbcl-$VERSION-x86-linux
198 #  sh $SBCL_DIR/binary-distribution.sh sbcl-$VERSION-x86-linux
199 #fi
200
201 ## Checksum
202
203 if [ ! -f $SBCL_RELEASE_DIR/sbcl-$VERSION-$SFUSER ]; then
204   cd $SBCL_RELEASE_DIR
205   echo "The SHA256 checksums of the following distribution files are:" > sbcl-$VERSION-$SFUSER
206   echo >> sbcl-$VERSION-$SFUSER
207   sha256sum sbcl-$VERSION*.tar >> sbcl-$VERSION-$SFUSER
208   bzip2 sbcl-$VERSION*.tar
209 fi
210
211 ## Bug closing email
212
213 if [ ! -f $SBCL_RELEASE_DIR/sbcl-$VERSION-bugmail.txt ]; then
214   cd $SBCL_RELEASE_DIR
215   echo Bugs fixed by sbcl-$VERSION release > sbcl-$VERSION-bugmail.txt
216  for bugnum in $(egrep -o "#[1-9][0-9][0-9][0-9][0-9][0-9]+" sbcl-$VERSION-release-notes.txt | sed s/#// | sort -n); do 
217     printf "\n bug %s\n status fixreleased" $bugnum >> sbcl-$VERSION-bugmail.txt
218   done
219   echo >> sbcl-$VERSION-bugmail.txt
220 fi
221
222 ## Sign
223
224 if [ ! -f $SBCL_RELEASE_DIR/sbcl-$VERSION-$SFUSER.asc ]; then
225   cd $SBCL_RELEASE_DIR
226   gpg -sta $SBCL_RELEASE_DIR/sbcl-$VERSION-$SFUSER
227 fi
228
229 ## Upload to sf.net
230
231 if [ ! -f $SBCL_RELEASE_DIR/uploaded ]; then
232
233   read -n 1 -p "Ok to upload? " A; echo  
234   if [ $A \!= "y" ]; then
235     exit 1
236   fi
237
238   cd $SBCL_RELEASE_DIR
239 cat > $SBCL_RELEASE_DIR/sftp-batch <<EOF
240 cd /home/frs/project/s/sb/sbcl/sbcl
241 mkdir $VERSION
242 chmod 775 $VERSION
243 cd $VERSION
244 put sbcl-$VERSION-$SFUSER.asc
245 put sbcl-$VERSION-x86-64-linux-binary.tar.bz2
246 put sbcl-$VERSION-source.tar.bz2
247 put sbcl-$VERSION-documentation-html.tar.bz2
248 put sbcl-$VERSION-release-notes.txt
249 put sbcl-$VERSION-release-notes.txt README
250 EOF
251   sftp -b $SBCL_RELEASE_DIR/sftp-batch $SFUSER,sbcl@frs.sourceforge.net 
252   touch uploaded
253 fi
254
255 ## Push
256
257 if [ ! -f $SBCL_RELEASE_DIR/sbcl-git-pushed ]; then
258   cd $GIT_DIR
259   git diff origin || true
260   
261   read -n 1 -p "Ok? " A; echo  
262
263   if [ $A = "y" ]; then
264     git push
265     git push --tags
266     touch $SBCL_RELEASE_DIR/sbcl-git-pushed
267   else
268     exit 1
269   fi
270 fi
271
272 ## Build + push documentation
273
274 if [ ! -f $SBCL_RELEASE_DIR/sbcl-page-uploaded ]; then
275   cp -af $GIT_DIR/../sbcl-page $SBCL_RELEASE_DIR
276   cd $SBCL_RELEASE_DIR/sbcl-page/sbcl
277   git fetch
278   cd $SBCL_RELEASE_DIR/sbcl-page
279   git pull
280   git submodule update
281   cp $SBCL_DIR/NEWS .
282   perl -i -pe "s/(:x86-64 :linux :available) \".*\"/\$1 \"$VERSION\"/" \
283     platform-support-platforms.lisp
284
285   export LC_CTYPE=en_GB.utf8
286
287   ## FIXME: this depends on the sbcl-$VERSION tag being visible on sf
288   ## git, not just the local machine (because of the submodule), which
289   ## means that the release.sbcl should have as its origin sf not
290   ## another local copy.
291   nice -20 make manual generate-pages SBCL_TAG=sbcl-$VERSION >>$LOGFILE 2>&1
292
293   COMMIT=false
294
295   git diff || COMMIT=true  
296   links -dump platform-table.html
297
298   read -n 1 -p "Ok? " A; echo  
299
300   if [ $A = "y" ]; then
301     if [ $COMMIT ]; then
302       git commit -a -m "Update for $VERSION"
303       git push
304     fi
305     make upload-pages upload-manual SBCL_TAG=sbcl-$VERSION
306     touch $SBCL_RELEASE_DIR/sbcl-page-uploaded
307   else
308     exit 1
309   fi
310 fi
311
312 set +x
313
314 echo TODO:
315 echo 
316 echo perform administrative tasks:
317 echo 
318 echo \* https://sourceforge.net/project/admin/?group_id=1373
319 echo \* In the File Manager interface, click on \"information\" for the
320 echo \ \ source tarball and select as default download for all OSes.
321 echo \* mail sbcl-announce
322 echo \* check and send sbcl-$VERSION-bugmail.txt to edit@bugs.launchpad.net
323 echo \ \ '(sign: C-c RET s p)'
324 echo "* update #lisp IRC topic (requires channel ops)"