#!/bin/bash # Copyright (C) 2011-2013 by Mike Gabriel # # This programme is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This programme is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. export PATH=~/bin:$PATH GIT_USER="gituser" GIT_HOSTNAME="git.mydomain.org" RPMEMAIL="firstname.lastname@mydomain.org" RPMFULLNAME="Firstname Lastname" GPG_KEY= DISTS_SUPPORTED="fedora epel" FEDORA_DISTROS="18,19,20,rawhide" EPEL_DISTROS="6" RPM_REPOS_BASE=/var/www/ COMPONENT_MAIN="main" COMPONENT_NIGHTLY="nightly" COMPONENT_BUNDLES="bundle-release1 bundle-release2" REPOS_SERVER="packages.mydomain.org" PACKAGES_WITHOUT_OTHERMIRROR="keyring" GNUPGHOME=$HOME/.gnupg FORCE_BUILD=${FORCE_BUILD:-"no"} RPM_BUILD_FOR=${RPM_BUILD_FOR:-"fedora:$FEDORA_DISTROS epel:$EPEL_DISTROS"} test -z $1 && { echo "usage: $(basename $0) [/] {main,main/,nightly,nightly/} []"; exit -1; } PREFIX=$(echo `basename $0` | cut -d"-" -f1) test -f ~/.buildscripts/$PREFIX.conf && . ~/.buildscripts/$PREFIX.conf || { echo "$0 has no valid context prefix..."; exit -1; } set -ex set_vars() { TEMP_BASE="$HOME/tmp/" mkdir -p "$TEMP_BASE" chmod 2770 "$TEMP_BASE" # first argv is the name of the Git project PROJECT_PATH="$1" PROJECT_PATH=${PROJECT_PATH/%.git/} PROJECT="$(basename $PROJECT_PATH)" # grab repository component area from command line (2nd argv) or guess it ARGV2_COMPONENT="$(echo "$2/" | cut -d"/" -f1)" ARGV2_CODENAME="$(echo "$2/" | cut -d"/" -f2)" COMPONENT="${ARGV2_COMPONENT:-${COMPONENT:-$COMPONENT_NIGHTLY}}" CODENAMES="${ARGV2_CODENAME:-${CODENAMES}}" [ -n "$ARGV2_CODENAME" ] && FORCE_BUILD="yes" || true DATE="${DATE:-$(date +%Y%m%d)}" if [ "x$COMPONENT" = "x$COMPONENT_MAIN" ]; then CHECKOUT="${3:-build-main}" elif echo "$COMPONENT_RELEASES" | grep "$COMPONENT" >/dev/null; then CHECKOUT="${3:-build-$COMPONENT}" elif [ "x$COMPONENT" = "x$COMPONENT_NIGHTLY" ]; then CHECKOUT="${3:-master}" else echo "error: no such package component area for this Git project. Aborting..." exit -1 fi # the DATE might be given as ,,today'' from the command line [ "x$DATE" = "xtoday" ] && DATE="$(date +%Y%m%d)" # setting paths PROJECT_DIR="$HOME/build/$COMPONENT/$PROJECT" PKGDIST="$HOME/pkg-dist/$COMPONENT/$PROJECT" # creating paths mkdir -p "$TEMP_BASE" mkdir -p "$PROJECT_DIR" mkdir -p "$PKGDIST" return 0 } prepare_workspace() { # create rpmbuild subdirectories mkdir -p $PKGDIST/rpmbuild/SOURCES # make sure our local working copy is up to date... if [ -d "$PROJECT_DIR/.git" ]; then cd "$PROJECT_DIR" && git reset --hard git checkout --force $CHECKOUT || git checkout --force -b $CHECKOUT git pull origin $CHECKOUT git fetch origin upstream:upstream || true git fetch origin pristine-tar:pristine-tar || true # and again, get the $CHECKOUT refspec in pure state git reset --hard git clean -df else cd "$(dirname $PROJECT_DIR)" git clone git://$GIT_HOSTNAME/$PROJECT_PATH.git cd "$PROJECT" git checkout --force $CHECKOUT || git checkout --force -b $CHECKOUT; git fetch origin upstream:upstream git fetch origin pristine-tar:pristine-tar || true git clean -df fi GIT_OBJECT_ID=`git show-ref -s heads/master` cd "$PROJECT_DIR" if [ "x$ARGV2_CODENAME" != "x" ]; then if echo "$FEDORA_DISTROS" | grep $ARGV2_CODENAME >/dev/null; then RPM_BUILD_FOR="fedora:$ARGV2_CODENAME" elif echo "$EPEL_DISTROS" | grep $ARGV2_CODENAME >/dev/null; then RPM_BUILD_FOR="epel:$ARGV2_CODENAME" fi fi return 0 } clear_pkgdist() { # pkgdist directory cleanup echo "$RPM_BUILD_FOR" | sed -e 's/ /\n/g' | while read line; do l_DIST="$(echo ${line/: /:} | cut -d":" -f1 | tr [:upper:] [:lower:])" l_CODENAMES="${CODENAMES:-$(echo ${line/: /:} | cut -d":" -f2- | sed -e 's/,/ /g' | tr [:upper:] [:lower:])}" echo "$DISTS_SUPPORTED" | grep $l_DIST >/dev/null && { for l_CODENAME in $l_CODENAMES; do # in case we build a special CODENAME (squeeze, wheezy, lucid, ...) do skip # the wrong distribution here... test -z $CODENAMES || echo $line | grep $CODENAMES || break for l_ARCH in x86_64 i386; do [ "x$SKIP_ARCH" != "x$l_ARCH" ] && { mkdir -p "$PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH" #rm -f "$PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/dupload.conf" rm -f "$PKGDIST/rpmbuild/SOURCES/$PROJECT-"*.tar.gz rm -f "$PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/"*.log rm -f "$PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH/$PROJECT-"*.rpm } done done } done return 0 } build_packages() { # tar upstream sources from our Git clone TEMP_DIR="$(mktemp -d --tmpdir=$TEMP_BASE)" mkdir -p "$TEMP_DIR/$PROJECT" chmod 2770 "$TEMP_DIR" -Rf cd "$PROJECT_DIR" git clone --local "$PROJECT_DIR" "$TEMP_DIR/$PROJECT/" cd $TEMP_DIR GITREV=$(cd $PROJECT && gitrevno && cd - 1>/dev/null) rm -Rf "$PROJECT/.git" mv $PROJECT/$PROJECT.spec . UPSTREAM_VERSION=$(cat $PROJECT.spec | egrep "^Version:.*" | awk '{ print $2 }') PKG_RELEASE=$(cat $PROJECT.spec | egrep "^Release:.*" | awk '{ print $2 }') PKG_SRCRELEASE=$(echo $PKG_RELEASE | sed -e 's/%{?dist}//') IS_NOARCH=$(cat $PROJECT.spec | egrep "^BuildArch:.*noarch\$" 1>/dev/null 2>/dev/null && echo yes || echo no) if [ "$COMPONENT" = "$COMPONENT_NIGHTLY" ]; then IS_RELEASE="0" else IS_RELEASE="1" fi sed -i $PROJECT.spec -e "s/%{?dist}/.$IS_RELEASE.git$DATE.$GITREV.$COMPONENT%{?dist}/" mv $TEMP_DIR/$PROJECT $TEMP_DIR/$PROJECT-$UPSTREAM_VERSION tar -czf $PKGDIST/rpmbuild/SOURCES/$PROJECT-$UPSTREAM_VERSION.tar.gz $PROJECT-$UPSTREAM_VERSION # create the SRPM package rpmbuild -D "%_topdir $PKGDIST/rpmbuild" -bs $PROJECT.spec # clean up the Git clone from the temp folder cd && rm $TEMP_DIR/$PROJECT -Rf echo "$RPM_BUILD_FOR" | sed -e 's/ /\n/g' | while read line; do l_DIST="$(echo ${line/: /:} | cut -d":" -f1 | tr [:upper:] [:lower:])" l_CODENAMES="${CODENAMES:-$(echo ${line/: /:} | cut -d":" -f2- | sed -e 's/,/ /g' | tr [:upper:] [:lower:])}" echo "$DISTS_SUPPORTED" | grep $l_DIST >/dev/null && { for l_CODENAME in $l_CODENAMES; do test -z $CODENAMES || echo $line | grep $CODENAMES || break # modify changelog for this build ### TODO: add changelog entry for this automatic build mkdir -p $PKGDIST/$l_DIST/$l_CODENAME/{x86_64,i386} # TODO: obtain packages from our YUM repository??? #OTHERMIRROR="" #if [ "x$COMPONENT" = "x$COMPONENT_NIGHTLY" ]; then # echo $PACKAGE_WITHOUT_OTHERMIRROR | grep $PROJECT >/dev/null || OTHERMIRROR="deb http://$REPOS_SERVER/$l_DIST $l_CODENAME $COMPONENT_MAIN $COMPONENT" #else # echo $PACKAGE_WITHOUT_OTHERMIRROR | grep $PROJECT >/dev/null || OTHERMIRROR="deb http://$REPOS_SERVER/$l_DIST $l_CODENAME $COMPONENT" #fi if [ "x$SKIP_ARCH" != "xx86_64" ] || [ "$IS_NOARCH" = "yes" ]; then mock -r ${l_DIST}-${l_CODENAME}-x86_64 --result $PKGDIST/$l_DIST/$l_CODENAME/x86_64 $PKGDIST/rpmbuild/SRPMS/$PROJECT-$UPSTREAM_VERSION-$PKG_SRCRELEASE.$IS_RELEASE.git$DATE.$GITREV.$COMPONENT.src.rpm rpmsign-unattended -D "%_gpg_name debian@x2go.org" --addsign $PKGDIST/$l_DIST/$l_CODENAME/x86_64/*.rpm fi if [ "x$SKIP_ARCH" != "xi386" ] && [ "$IS_NOARCH" != "yes" ]; then mock -r ${l_DIST}-${l_CODENAME}-i386 --result $PKGDIST/$l_DIST/$l_CODENAME/i386 $PKGDIST/rpmbuild/SRPMS/$PROJECT-$UPSTREAM_VERSION-$PKG_SRCRELEASE.$IS_RELEASE.git$DATE.$GITREV.$COMPONENT.src.rpm rpmsign-unattended -D "%_gpg_name debian@x2go.org" --addsign $PKGDIST/$l_DIST/$l_CODENAME/i386/*.rpm fi done } done rm -Rf "$TEMP_DIR" return 0 } upload_packages() { # dupload the new packages to the reprepro repository echo "$RPM_BUILD_FOR" | sed -e 's/ /\n/g' | while read line; do l_DIST="$(echo ${line/: /:} | cut -d":" -f1 | tr [:upper:] [:lower:])" l_CODENAMES="${CODENAMES:-$(echo ${line/: /:} | cut -d":" -f2- | sed -e 's/,/ /g' | tr [:upper:] [:lower:])}" for l_CODENAME in $l_CODENAMES; do # in case we build a special CODENAME (squeeze, wheezy, lucid, ...) do skip # the wrong distribution here... test -z $CODENAMES || echo $line | grep $CODENAMES || break for l_ARCH in x86_64 i386; do [ "x$SKIP_ARCH" != "x$l_ARCH" ] && { # create remote directories in archive ssh $REPOS_SERVER mkdir -p $RPM_REPOS_BASE/$l_DIST/$COMPONENT/$l_CODENAME/$l_ARCH/rpms ssh $REPOS_SERVER mkdir -p $RPM_REPOS_BASE/$l_DIST/$COMPONENT/$l_CODENAME/$l_ARCH/repodata # remove rpm packages of the same name (pattern) ssh $REPOS_SERVER rm -f $RPM_REPOS_BASE/$l_DIST/$COMPONENT/$l_CODENAME/$l_ARCH/rpms/$PROJECT.*.rpm # copy rpms into repo cd "$PKGDIST/$l_DIST/$l_CODENAME/$l_ARCH" scp *.rpm $REPOS_SERVER:$RPM_REPOS_BASE/$l_DIST/$COMPONENT/$l_CODENAME/$l_ARCH/rpms/ || true ssh $REPOS_SERVER "cd $RPM_REPOS_BASE/$l_DIST/$COMPONENT/$l_CODENAME/$l_ARCH/ && createrepo ." } done done done return 0 } ### MAIN ### set_vars $@ && { if [ "x$(basename $0)" = "x$PREFIX-build-rpm-package" ] || [ "x$(basename $0)" = "x$PREFIX-build+upload-rpm-package" ]; then cd $PROJECT_DIR && pkgneedsbuild $CHECKOUT || [ "$FORCE_BUILD" = "yes" ] && { prepare_workspace && { clear_pkgdist build_packages } } fi if [ "x$(basename $0)" = "x$PREFIX-upload-rpm-package" ] || [ "x$(basename $0)" = "x$PREFIX-build+upload-rpm-package" ]; then upload_packages fi }