Last active
August 29, 2015 14:19
-
-
Save allex/fbe05460d1f4005047ad to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # Toolkit script for git repos build and distribute release. | |
| # Author: Allex Wang ([email protected]) | |
| # GistID: fbe05460d1f4005047ad | |
| dir=`cd $(dirname $0); pwd -P` | |
| source=$dir/source | |
| [ -d $source ] || { echo >&2 "source dir not exists." && exit 404; } | |
| out=$dir/out | |
| lockfile=$out/.lock | |
| verfile=$out/.version | |
| rebuild=1 | |
| force=0 | |
| publish=0 | |
| exclude=( ".svn" ".git" ) | |
| while getopts ":u:b:m:d:e:fi" opt | |
| do | |
| case $opt in | |
| u) repo_url=$OPTARG ;; | |
| b) branch=$OPTARG ;; | |
| m) IFS="," read -ra mods <<< "$OPTARG" | |
| has_topic=0 | |
| for i in "${mods[@]}"; do | |
| [ "$i" == "topic" ] && { has_topic=1; break; } | |
| done | |
| [ $has_topic -eq 1 ] || exclude+=("*topic/*") | |
| ;; | |
| d) IFS="," read -ra server <<< "$OPTARG" ;; | |
| f) force=1 ;; | |
| i) rebuild=0 ;; | |
| e) [ "$OPTARG" == "pro" ] && publish=1 ;; | |
| :) echo >&2 "Option -$OPTARG requires an argument." | |
| exit 500 | |
| ;; | |
| esac | |
| done | |
| if [ -z "$mods" ]; then | |
| echo "" | |
| echo "$(basename $0) [-f] [-m module_list] [-e environment]" | |
| echo "" | |
| echo " -m <module_name> A comma-separated module list to build, eg. public,admin" | |
| echo "" | |
| exit 1; | |
| fi | |
| if [ -f $lockfile ] | |
| then | |
| if [ $force -eq 1 ]; then | |
| kill -9 `cat $lockfile` | |
| rm -f $lockfile; | |
| else | |
| pid=`cat $lockfile` | |
| if ps -p $pid > /dev/null | |
| then | |
| user=`ps aux|awk -v PID=$pid '$2 == PID { print $1 }'` | |
| echo >&2 "[$user] build is running... (exit 1)" && exit 406; | |
| fi | |
| fi | |
| fi | |
| if [ -d $source/.git ] | |
| then | |
| if [ -z "$branch" ]; then | |
| branch=$(cd $source && git rev-parse --abbrev-ref HEAD); | |
| fi | |
| echo "Current branch: $branch" | |
| if [ $rebuild -eq 1 ]; then | |
| eval "cd $source && git fetch origin && git reset --hard origin/$branch" | |
| fi | |
| rev=`cd $source && git rev-parse --short HEAD` | |
| else | |
| if [ -d $source/.svn ] ; then | |
| svn up $source >/dev/null 2>&1 | |
| echo "Update source from remote repository, done" | |
| fi | |
| fi | |
| VERSION="" | |
| ts=${rev}.$(date +%s) | |
| tarball="/tmp/build_${ts}.tgz" | |
| exclude_pattern="" | |
| init() | |
| { | |
| for i in "${exclude[@]}"; do | |
| exclude_pattern+=" --exclude \"$i\"" | |
| done | |
| trap eof SIGINT SIGTERM | |
| echo $$ >$lockfile | |
| } | |
| eof() | |
| { | |
| [ -f $tarball ] && rm -rf $tarball | |
| [ -f $lockfile ] && rm -rf $lockfile | |
| exit 1; | |
| } | |
| dist() | |
| { | |
| [ -f $tarball ] || { eval "cd $out && tar czf $tarball $exclude_pattern ./"; } | |
| local list=() | |
| local mode=0 | |
| if [ -n "$server" ]; then | |
| list=( ${server[@]} ) | |
| mode=1 | |
| else | |
| read -t 40 -p "Enter the server name to distribute (q to exit): " | |
| local ex=$? | |
| local ip=$REPLY | |
| # timeout exit. | |
| [ $ex -eq 0 ] || return $ex | |
| [ "$ip" != "q" ] || return 1; | |
| local IFS="," | |
| list=( $ip ) | |
| fi | |
| if [ -n "${list}" ]; then | |
| # distribute release | |
| remote_dir="/apps/data/web/working/static5.bubugao.com/" | |
| for i in "${list[@]}" | |
| do | |
| target=${i}:${remote_dir} | |
| echo "Releasing to ${target} ..." | |
| if ssh -q -o StrictHostKeyChecking=no -o BatchMode=yes $i true; then | |
| scp -rpq $tarball "apps@$i:$tarball" && ssh apps@$i "mkdir -p \"$remote_dir\"; tar xzf $tarball -C \"$remote_dir\"; rm -f $tarball" && echo "Done. (build: $ts)" | |
| else | |
| echo >&2 "Host key verification failed." | |
| fi | |
| done | |
| fi | |
| [ $mode -eq 1 ] || dist; | |
| } | |
| cleanup_dist() | |
| { | |
| if [ -d $out/.svn ]; then | |
| svn revert $out -R >/dev/null | |
| svn st $out | grep '^?' | awk '{print $2}' | xargs rm -rf | |
| svn up $out >/dev/null 2>&1 | |
| fi | |
| } | |
| commit_dist() | |
| { | |
| if [ -d $out/.svn ]; then | |
| local st="svn status $out" | |
| if [ -n "$st" ]; then | |
| $st |sed -e '/^?/!d' -e 's/^? *//' |xargs -I{} svn add '{}@' >/dev/null 2>&1 | |
| $st |sed -e '/^!/!d' -e 's/^! *//' |xargs -I{} svn rm '{}@' >/dev/null 2>&1 | |
| fi | |
| svn status $out | |
| fi | |
| echo | |
| } | |
| prompt_version() | |
| { | |
| local ver="" | |
| local git="$1" | |
| # get version by user input | |
| read -t 600 -p "Please enter the version for release (eg: v0.0.1): " ver | |
| local ex=$? | |
| [ $ex -eq 0 ] || return $ex | |
| if [ -z "$ver" ]; then | |
| prompt_version; | |
| else | |
| if ! [[ "$ver" =~ ^v[0-9]+.[0-9]+.[0-9]+ ]]; then | |
| echo "Not a valid version." | |
| prompt_version && return; | |
| fi | |
| VERSION="${ver}" | |
| if $git rev-parse ${VERSION} >/dev/null 2>&1; then | |
| echo "tag exist (${VERSION})." | |
| prompt_version; | |
| fi | |
| fi | |
| } | |
| build() | |
| { | |
| if [ $publish -eq 1 ]; then | |
| cleanup_dist | |
| fi | |
| if [ $rebuild -ne 0 ]; then | |
| args="$@" | |
| if [[ ! "$args" =~ "-f " ]]; then | |
| args="${args} -c $dir/build.json" | |
| fi | |
| if [[ ! "$args" =~ "-o " ]]; then | |
| args="${args} -o $out" | |
| fi | |
| node $dir/bin/build.js $args | |
| echo $ts >$verfile | |
| fi | |
| } | |
| # commit release | |
| release() | |
| { | |
| if [ $publish -eq 1 ]; then | |
| commit_dist | |
| local red=$(tput setaf 1) | |
| local reset=$(tput sgr0) | |
| read -t 180 -p "${red}Commit to release branche? [y|n]${reset} " | |
| if [ "$REPLY" = "y" ]; then | |
| git="git --git-dir=${source}/.git --work-tree=${source}" | |
| $git fetch --tags &>/dev/null | |
| prompt_version "$git" | |
| if [ -n "$VERSION" ]; then | |
| local msg="Release $VERSION" | |
| svn ci $out -m "$msg" --force-log | |
| [ $? -eq 0 ] && $git tag "${VERSION}" -m "Release $msg" && $git push origin --tags | |
| echo "$msg, done" | |
| else | |
| echo "${red}Release build cancelled.${reset}" | |
| fi | |
| fi | |
| fi | |
| } | |
| init | |
| build "$@" | |
| dist | |
| release | |
| eof | |
| # vim: set fdm=manual ts=2 sw=2 sts=2 tw=85 et : |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment