autopkg.sh 5.76 KB
Newer Older
Dimitris Aragiorgis's avatar
Dimitris Aragiorgis committed
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
#!/bin/bash

usage(){

  echo "
Usage: $0: [options]
  -h, --help          Prints this help message
  --debian [branch]   Local debian branch to use (default debian)
  --upstream [branch] Local upstream branch to use (default master)
  --remote [repo]     Remote repo to use (default origin)
  --packages [dir]    Where to store the created packages (default ~/packages)
  --validate          Fetch remote repo branches and
                      check if local are up-to-date (default false)
  --push              Whether to push upstream (default false)
"
  exit 1
}

parse_git_branch()
{
    git branch 2> /dev/null | grep '^*' | sed 's/^*\ //g'
}

die()
{
    echo -e $* 1>&2
    echo Aborting.
    exit 1
}

cleanup()
{
    trap - EXIT

    echo -n Cleaning up...
    if [ ${#CLEANUP[*]} -gt 0 ]; then
        LAST_ELEMENT=$((${#CLEANUP[*]}-1))
        REVERSE_INDEXES=$(seq ${LAST_ELEMENT} -1 0)
        for i in $REVERSE_INDEXES; do
            local cmd=${CLEANUP[$i]}
            $cmd
        done
    fi
    echo "done"
}

add_cleanup() {
    local cmd=""
    for arg; do cmd+=$(printf "%q " "$arg"); done
    CLEANUP+=("$cmd")
}


add_checkpoint()
{
    commit=$(git reflog | head -n1 | cut -f 1 -d " ")
    add_cleanup git reset --hard $commit
    LASTCHECKPOINT=$commit
}

CLEANUP=( )


TEMP=$(getopt -o h --long help,validate,push,packages:,upstream:,debian:,remote: -n 'autopkg.sh' -- "$@")

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

eval set -- "$TEMP"

while true ; do
  case "$1" in
    -h|--help) usage ;;
    --upstream) LOCALUPSTREAM=$2 ; shift 2 ;;
    --debian) LOCALDEBIAN=$2 ; shift 2 ;;
    --remote) REMOTE=$2 ; shift 2 ;;
    --packages) PKGAREA=$2 ; shift 2 ;;
    --validate) VALIDATE=true ; shift ;;
    --push) PUSH=true ; shift ;;
    --) shift ; break ;;
    *) echo "Internal error!" ; usage ;;
  esac
done

# The root of the git repository, no matter where we're called from
TOPLEVEL="$(git rev-parse --show-toplevel)"

: ${LOCALUPSTREAM:=$(parse_git_branch)}
: ${LOCALDEBIAN:=debian}
: ${REMOTE:=origin}
: ${VALIDATE:=false}
: ${PUSH:=false}

: ${PKGAREA:=~/packages}
: ${BACKUPAREA:=~/backup}

cd "$TOPLEVEL"

# Prerequisites: Test all important directories exist
test -d "$PKGAREA" || die "Package area directory $PKGAREA missing"
test -d "$BACKUPAREA" || die "Backup area directory $BACKUPAREA missing"

# Prerequisite: Test the dialog utility is available
dialog --help &>/dev/null || die "Could not run the 'dialog' utility"

BUILDAREA=$(mktemp -d --tmpdir=/tmp build-area.XXX)
add_cleanup rm -r $BUILDAREA

echo "############################################################################"
echo "Will build packages under $BUILDAREA"
echo "Local upstream branch: $LOCALUPSTREAM"
echo "Local debian branch: $LOCALDEBIAN"
$VALIDATE && echo "Will fetch $REMOTE and check if $LOCALUPSTREAM and $LOCALDEBIAN are up-to-date"
echo "############################################################################"
echo "Press Enter to continue..."
read

MODIFIED=$(git status --short | grep -v "??")
test -z "$MODIFIED" || die "error: Repository is dirty. Commit your local changes:\n $MODIFIED"

set -e
trap cleanup EXIT

add_checkpoint

# Create a temporary debian branch to do everything
TMPDEBIAN=$(mktemp -u debian.XXX)
git branch --track $TMPDEBIAN  $LOCALDEBIAN
add_cleanup git branch -D $TMPDEBIAN

git checkout $TMPDEBIAN
add_cleanup git checkout $LOCALUPSTREAM

# Whether we are in snapshot or release mode
snap=false
mrgextra=-m
dchextra=-R
mrgmsg="Merge branch '$LOCALUPSTREAM' into $LOCALDEBIAN"
dialog --yesno "Create Snapshot?" 5 20 && snap=true  && dchextra=-S && mrgextra= && mrgmsg=

# merge local branch into tmp branch with a nice commit message,
# so it can be pushed as is to upstream debian
export GIT_MERGE_AUTOEDIT=no
git merge $mrgextra ${mrgextra:+"$mrgmsg"} $LOCALUPSTREAM

# auto edit Debian changelog depending on Snapshot or Release mode
export EDITOR=/usr/bin/vim
git-dch --debian-branch=$TMPDEBIAN --git-author --ignore-regex=".*" --multimaint-merge --since=HEAD $dchextra
git add debian/changelog

# get version from the changelog
# we add a git tag here, so setup.py sdist works as expected
# FIXME: This is a workaround for the way Synnefo packages determine
#        the versions for their Python packages
version=$(IFS="()" ; read  x v x < debian/changelog  ; echo $v)
if ! $snap; then
  git commit -s -a -m "Bump new upstream version"
  TAGFILE=$(mktemp -t tag.XXX)
  add_cleanup rm $TAGFILE
  dialog --inputbox "New Debian Tag: " 5 30 "debian/$version" 2>$TAGFILE
  git tag $(<$TAGFILE)
  add_cleanup git tag -d $(<$TAGFILE)
fi

add_cleanup git reset --hard HEAD
# Build all packages
git-buildpackage --git-export-dir="$BUILDAREA" \
                 --git-upstream-branch=$LOCALUPSTREAM \
                 --git-debian-branch=$TMPDEBIAN \
                 --git-export=INDEX \
                 --git-ignore-new -sa

# do some dirty backup
# pkgarea might be needed by auto-deploy tool
rm -f "$PKGAREA"/* || true
cp -v "$BUILDAREA"/* "$PKGAREA"/ || true
cp -v "$BUILDAREA"/* "$BACKUPAREA"/ || true



function check_remote(){

  git fetch $1 2>/dev/null || die "Could not fetch $1"
  git fetch $1 $2 2>/dev/null|| die "Could not fetch $1/$2"

  commits_behind=$(git rev-list $2..$1/$2 | wc -l)
  if [ $commits_behind -ne 0 ]; then
    die "Your local branch is outdated. Please run:\ngit pull --rebase $1/$2"
  fi


}

if $VALIDATE; then
  check_remote $REMOTE $LOCALUPSTREAM
  check_remote $REMOTE $LOCALDEBIAN
fi


  # trap - EXIT
  # here we can push the commits to the remote debian branch as they are
echo
echo "#################################################"
echo "##                  SUCCESS                    ##"
echo "#################################################"
if $PUSH; then
  git push --tags $REMOTE $TMPDEBIAN:$LOCALDEBIAN
  git push $REMOTE $LOCALUPSTREAM:$LOCALUPSTREAM
fi

exit 0