mirror of https://github.com/Chizi123/Arch-autobuild-repo.git

Joel Grunbaum
2020-03-29 8ea4ef181e92bfe5f410e365b8ed614f939c8da1
Large change to overall structure, moved to one file
1 files modified
8 files deleted
1 files added
428 ■■■■■ changed files
README.org 30 ●●●●● patch | view | raw | blame | history
add_dependency.sh 24 ●●●●● patch | view | raw | blame | history
add_package.sh 24 ●●●●● patch | view | raw | blame | history
autobuild.service 9 ●●●●● patch | view | raw | blame | history
autobuild.timer 9 ●●●●● patch | view | raw | blame | history
build.sh 150 ●●●●● patch | view | raw | blame | history
build_packages.sh 6 ●●●●● patch | view | raw | blame | history
enter_chroot.sh 6 ●●●●● patch | view | raw | blame | history
fix_AUR.sh 7 ●●●●● patch | view | raw | blame | history
main.sh 163 ●●●●● patch | view | raw | blame | history
README.org
@@ -1,28 +1,32 @@
#+TITLE: Auto-build package repository for Arch Linux
* What is this?
This is a set of files to auto-build a personal repository for Arch.
It uses a chroot environment to build the packages, so that a build environment can be made on a server running a non-arch operating system.
This is a package autobuild solution for Arch Linux.
It supports the automated building of packages from the AUR.
Currently it supports package signing and building clean from source.
It can help to set itself up and generate GPG keys if need be.
The chroot files are here from an older version of this project and are here as I think they're interesting.
* Set-up
Edit ~create_chroot.sh~ variables at the top to your details.
Run ~sudo create_chroot.sh~, and create the git repository in ~/build/repo~ when prompted, with a remote repository.
Edit the variables at the top of ~main.sh~ to suit your repository details.
Have a look at the init function near the bottom of the file to decide if you want to run it.
If you decide to generate a GPG key, edit the name, comment and email so that it fits you.
You may also want to set ~MAKEFLAGS="-j$(nproc)"~ within the chroot to enable parallel compilation.
For xz compression, add the ~--threads=0~ option to COMPRESSXZ such that it reads ~COMPRESSXZ=(xz -c -z - --threads=0)~.
ccache may be useful to decrease the times of git packages, due to the little changes.
* Usage
All scripts must be run as root.
To enter the chroot, use the ~enter_chroot.sh~ script.
To add a package from the AUR, use the ~add_package.sh~ script, with the git URL as the argument.
To build the packages use the ~build_packages.sh~ script, which will enter the chroot, and build the packages from the PKGBUILDs stored in ~/build/repo~.
The packages are built and put into the directory ~/build/repo/x86_64~, then pushed with git.
Only the latest packages are stored in ~/build/repo/x86_64~ to avoid multiple older versions building up.
To enable automatic building, create a cronjob for root, something of the sort of ~0 12 * * * /path/to/dir/build_packages.sh~ to build ever day at noon.
To add a package ~main.sh add [package]~ should be run. Currently I only support adding one package at a time.
To update all packages, use ~main.sh build-all~. A ~-f~ flag can be used to force a rebuild of all the packages.
To allow automatic building, use a cronjob or write a systemd unit, there are many guides out there, although I may add examples if I feel like it.
* To Dos
- Multiple packages from a single PKGBUILD
  Some PKGBUILDs can create many packages at once, currently I am unable to handle this.
- Error catching for builds which fail.
  Have emailing, but nothing more advanced. Would be nice to have some basic error handling in the script
- Create a universal variables file
  Not sure how useful this would be, but could be nice
add_dependency.sh
File was deleted
add_package.sh
File was deleted
autobuild.service
File was deleted
autobuild.timer
File was deleted
build.sh
File was deleted
build_packages.sh
File was deleted
enter_chroot.sh
File was deleted
fix_AUR.sh
File was deleted
main.sh
New file
@@ -0,0 +1,163 @@
#!/bin/bash
REPODIR=/repo/x86_64
BUILDDIR=/repo/build
REPONAME=
UPDATE=N
CLEAN=N
SIGN=N
KEY=""
NUM_OLD=5
export PACKAGER="John Doe <jd@change.me>"
EMAIL=""
ERRORS=""
#Helper for finding newest and oldest files
#Sourced from stack overflow
function newold_matching_file
{
    # Use ${1-} instead of $1 in case 'nounset' is set
    local -r glob_pattern=${2-}
    # To avoid printing garbage if no files match the pattern, set
    # 'nullglob' if necessary
    local -i need_to_unset_nullglob=0
    if [[ ":$BASHOPTS:" != *:nullglob:* ]] ; then
        shopt -s nullglob
        need_to_unset_nullglob=1
    fi
    file=
    for f in $glob_pattern ; do
        if [ $1 == "n" ]; then
            [[ -z $f || $f -nt $_file ]] && file=$f
        elif [ $1 == "o" ]; then
            [[ -z $f || $f -ot $_file ]] && file=$f
        fi
    done
    # To avoid unexpected behaviour elsewhere, unset nullglob if it was
    # set by this function
    (( need_to_unset_nullglob )) && shopt -u nullglob
    # Use printf instead of echo in case the file name begins with '-'
    [[ -n $file ]] && printf '%s\n' "$file"
    return 0
}
#Build latest version of a package
function build_pkg {
    #check if PKGBUILD has updated, don't rebuild if hasn't changed
    #rebuild if git is in filename (git tree may change without PKGBUILD)
    #rebuild if forced
    if [[ ! -z $(git pull | grep "Already up to date.") && -z $(echo $1 | grep git) && -z $2 ]]; then
        return 2
    fi
    makepkg -s --noconfirm $([ $CLEAN == "Y" ] && echo "-c") $([ $SIGN == "Y" ] && echo "--sign --key $KEY") $([ "$2" == "-f" ] && echo -f)
    if [ $? != 0 ]; then
        #Register error
        ERRORS=$(printf '%s %s' "$ERRORS" "$1")
        return 1
    fi
    #copy package to repo directory
    latest="$(newold_matching_file n '*.pkg.tar.xz')"
    cp $latest $REPODIR/$latest
    repo-add $([ "$SIGN" == "Y" ] && echo "--sign --key $KEY") $REPODIR/$REPONAME.db.tar.xz $REPODIR/$latest
    #Remove old versions of packages
    while [ $NUM_OLD \< $(find . -name '*.pkg.tar.xz' | wc -l) ]
    do
        old=$(newold_matching_file o '*.pkg.tar.xz')
        rm $REPODIR/$old $old
    done
    return 0
}
#Update packages in BUILDDIR
function build_all {
    #system update
    if [ $UPDATE == "Y" ]; then
        sudo pacman -Syu --noconfirm
    fi
    #update every package currently stored
    for d in $(find $BUILDDIR -maxdepth 1 -mindepth 1 -not -path '*/\.*' -type d)
    do
        cd $d
        build_pkg $(echo $d | rev | cut -d'/' -f1 | rev) $1
    done
    return 0
}
#Add a new package to be built
function add {
    cd $BUILDDIR
    git clone https://aur.archlinux.org/$1.git
    cd $1
    build_pkg $1 new
    return 0
}
#Check config and create build folders
function init {
    #check for configuration here
    [ -z $REPODIR ] && echo "Enter REPODIR" && return 1
    [ -z $BUILDDIR ] && echo "Enter BUILDDIR" && return 2
    [ -z $REPONAME ] && echo "Enter REPONAME" && return 3
    #make build directories
    [ ! -d $REPODIR ] && mkdir -p $REPODIR
    [ ! -d $BUILDDIR ] && mkdir -p $BUILDDIR
    #packages required to build others
    sudo pacman -S --noconfirm base-devel git
    #add repo to pacman.conf so can install own packages
    if [ -z $(grep "$REPONAME" /etc/pacman.conf) ]; then
        printf "[$REPONAME]\nSigLevel = Optional TrustAll\nServer = file://$REPODIR\n" >> /etc/pacman.conf
    fi
    #create GPG key for package signing
    if [ "$SIGN" == "Y" && "$KEY" == "" ]; then
        (
            echo "Key-Type: RSA"
            echo "Key-Length: 2048"
            echo "Subkey-Type: RSA"
            echo "Subkey-Length: 2048"
            echo "Passphrase: \"\""
            echo "Expire-Date: 0"
            echo "Name-Real: John Doe"
            echo "Name-Comment: Arch buildbot"
            echo "Name-Email: $(whoami)@localhost"
            echo "%commit"
        ) | gpg --batch --generate-key
        gpg --export --output $REPONAME.key --armor "John Doe"
        gpg --export-secret-keys --output $REPONAME.secret.key --armor "John Doe"
        echo "Please change the key information in this file"
    fi
    return 0
}
case $1 in
    "init")
        init;;
    "add")
        add $2;;
    "build-all")
        build_all $([ "$2" == "-f" ] && echo "-f")
        if [ "$ERRORS" != "" ]; then
            echo "Errors in packages $ERRORS"
            if [ "$EMAIL" != "" ]; then
                printf "Build for $(date)\nErrors found in $ERRORS\nPlease address these soon" | sendmail $EMAIL
            fi
        else
            echo "All packages built successfully"
        fi
        ;;
    *)
        printf "Invalid usage\nUsage: $0 init|add|build_all\n";;
esac