cloud/docker/release: build MacOS and Windows releases too

This also changes the layout of the release tree slightly, where we now
link 'latest/os_arch' to 'all/os_arch/sha' instead of linking each file
within 'latest/os_arch'. This makes it impossible for the tarball
builder to construct a tarball containing binaries built from different
commits.

Change-Id: Ia4bb09bf47d4eaaca6e95118ffaa4c9bf8503515
Reviewed-on: https://upspin-review.googlesource.com/10420
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/cloud/docker/release/makerelease.sh b/cloud/docker/release/makerelease.sh
index d6ce436..afca383 100755
--- a/cloud/docker/release/makerelease.sh
+++ b/cloud/docker/release/makerelease.sh
@@ -2,32 +2,72 @@
 
 # This script builds the Upspin commands and pushes them to release@upspin.io.
 # It is executed by the release Docker container.
+# The Docker container provides the Upspin repo in the /workspace directory and
+# sets the environment COMMIT_HASH variable to the current Git commit hash of
+# that repo.
 
 # The commands to build and distribute.
 # Command "upspin" must be one of these,
 # as it is used to copy the files to release@upspin.io.
 cmds="upspin upspinfs cacheserver"
 
-echo "Repo has base path $1"
+# The operating systems and processor architectures to build for.
+oses="darwin linux windows"
+arches="amd64"
+
+# Thet tree that contains the release binaries.
+user="release@upspin.io"
+
+echo 1>&2 "Repo has base path $1"
 mkdir -p /gopath/src
 cp -R /workspace/ /gopath/src/$1
 
-for cmd in $cmds; do
-	echo "Building $cmd"
-	/usr/local/go/bin/go get -v upspin.io/cmd/$cmd
+export GOOS
+export GOARCH
+for GOOS in $oses; do
+	for GOARCH in $arches; do
+		for cmd in $cmds; do
+			if [[ $GOOS == "windows" && $cmd == "upspinfs" ]]; then
+				# upspinfs doesn't run on Windows.
+				continue
+			fi
+			echo 1>&2 "Building $cmd for ${GOOS}_${GOARCH}"
+			/usr/local/go/bin/go get -v upspin.io/cmd/$cmd
+		done
+	done
 done
 
-up="/gopath/bin/upspin -config=/config"
-user="release@upspin.io"
-osarch="linux_amd64"
-destdir="$user/all/$osarch/$COMMIT_SHA"
-linkdir="$user/latest/$osarch"
-for cmd in $cmds; do
-	echo "Copying $cmd to release@upspin.io"
-	dest="$destdir/$cmd"
-	link="$linkdir/$cmd"
-	$up mkdir $destdir || echo 1>&2 "mkdir can fail if the directory exists"
-	$up cp /gopath/bin/$cmd $dest
-	$up rm $link || echo 1>&2 "rm can fail if the link does not already exist"
-	$up link $dest $link
+function upspin() {
+	/gopath/bin/upspin -config=/config "$@"
+}
+
+for GOOS in $oses; do
+	for GOARCH in $arches; do
+		osarch="${GOOS}_${GOARCH}"
+		srcdir="/gopath/bin"
+		if [[ $osarch != "linux_amd64" ]]; then
+			srcdir="$srcdir/$osarch"
+		fi
+		destdir="$user/all/$osarch/$COMMIT_SHA"
+		for cmd in $cmds; do
+			if [[ $GOOS == "windows" && $cmd == "upspinfs" ]]; then
+				# upspinfs doesn't run on Windows.
+				continue
+			fi
+			if [[ $GOOS == "windows" ]]; then
+				# Windows commands have a ".exe" suffix.
+				cmd="${cmd}.exe"
+			fi
+			src="$srcdir/$cmd"
+			dest="$destdir/$cmd"
+			link="$linkdir/$cmd"
+			echo 1>&2 "Copying $src to $dest"
+			upspin mkdir $destdir || echo 1>&2 "mkdir can fail if the directory exists"
+			upspin cp $src $dest
+		done
+		link="$user/latest/$osarch"
+		echo 1>&2 "Linking $link to $destdir"
+		upspin rm $link || echo 1>&2 "rm can fail if the link does not already exist"
+		upspin link $destdir $link
+	done
 done