aboutsummaryrefslogtreecommitdiff
path: root/packaging/run-in-docker
blob: 9fdaf2fc8ceeda348e74a2f1beb64eaff6634e2f (plain)
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
#!/bin/sh

set -eu

this="$(readlink -e ${0})"

# assign defaults
project_dir="$(dirname $(dirname ${this}))"
debian_tag="${DEBIAN_TAG:-sid}"

usage() {
    cat << EOF
Usage: $(basename ${this}) [OPTION]... [ACTION]
Run tests or create package in a docker container

Options:
    -h                print this usage and exit
    -C PROJECT_DIR    change to PROJECT_DIR (default: ${project_dir})
    -t DEBIAN_TAG     debian release tag (default: ${debian_tag})

Actions:
    help       print this usage and exit
    package    create debian package artifacts
    test       run tests (default)

Example:
    $(basename ${this}) -C ~/code/git-buildpackage -t stretch package
EOF
}

die() { { echo "ERROR: ${@}"; usage; } >&2; exit 1; }

# convenience wrapper
docker_build() {
    docker build \
        --force-rm=${DOCKER_BUILD_FORCE_RM:-false} \
        --no-cache=${DOCKER_BUILD_NO_CACHE:-false} \
        ${@}
}

# take path to project dir; build docker image for base
base_build() {
    (
        cd ${project_dir}
        [ -f .gitignore ] && cat .gitignore
        [ -f .gitmodules ] && sed -nr 's|\s+path = (.+)|\1|gp' .gitmodules
        cat <<EOF
${this##${PWD}/}
*.buildinfo
*.changes
*.deb
*.dsc
*.tar.xz
.dockerignore
.git*
EOF
    ) >${project_dir}/.dockerignore
    docker_build \
        --pull=${DOCKER_BUILD_PULL:-false} \
        --build-arg=FROM_IMAGE=debian:${debian_tag} \
        -t gbp-base:${debian_tag} -f- ${project_dir} <<'EOF'
arg FROM_IMAGE
from ${FROM_IMAGE}
env DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
workdir /workdir/project
run set -euvx \
  && apt-get update -y \
  && apt-get -y --no-install-recommends install \
       build-essential devscripts equivs
copy . .
run yes | mk-build-deps -ir
run groupadd luser && useradd -g luser luser && chown -R luser:luser ..
user luser
EOF
    rm -vf ${project_dir}/.dockerignore
}


# run tests
gbp_test() {
    base_build
    for L in C.UTF-8 C; do
        docker run --rm -ie"TEST_LOCALE=${L}" gbp-base:${debian_tag} sh <<'EOF'
set -euvx
make all+net
make -C docs
EOF
    done
}

# create debian package artifacts, copy to host
gbp_package() {
    base_build
    docker_build \
        --build-arg=FROM_IMAGE=gbp-base:${debian_tag} \
        -t gbp-package:${debian_tag} -f- ${project_dir} <<'EOF'
arg FROM_IMAGE
from ${FROM_IMAGE}
run dpkg-buildpackage -j$(nproc) -sa -us -uc
EOF
    docker run --rm -iu0:0 \
        --mount type=bind,source="${PWD}",target=/mnt/host-volume \
        gbp-package:${debian_tag} sh <<EOF
set -euvx
find .. -maxdepth 1 -mindepth 1 -type f \
    -exec chown -v $(id -u):$(id -g) {} + \
    -a -exec cp -vat /mnt/host-volume {} +
EOF
}

while getopts ":hC:t:" opt; do
    case $opt in
        h) usage; exit 0;;
        C) project_dir="$(readlink -e ${OPTARG})"
            [ -d "${project_dir}" ] || die "bad project dir ${OPTARG}";;
        t) debian_tag="${OPTARG}";;
        :) die "missing argument: -${OPTARG}";;
        \?) die "bad option: -${OPTARG}";;
    esac
done

shift $((${OPTIND} - 1))
case "${1:-test}" in
    'help') usage; exit 0;;
    'test') gbp_test; exit ${?};;
    'package') gbp_package; exit ${?};;
    \?) die "bad action: ${1}";;
esac