aboutsummaryrefslogtreecommitdiffhomepage
path: root/packaging/run-in-container
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/run-in-container')
-rwxr-xr-xpackaging/run-in-container145
1 files changed, 145 insertions, 0 deletions
diff --git a/packaging/run-in-container b/packaging/run-in-container
new file mode 100755
index 00000000..6d750078
--- /dev/null
+++ b/packaging/run-in-container
@@ -0,0 +1,145 @@
+#!/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 podman (or 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})
+ -c CONTAINER_CMD container runner command (default: podman)
+
+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
+# shellcheck disable=SC2068 # re-splitting command arguments intentional
+container_build() {
+ ${container_cmd} 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"
+ container_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 debian debian
+RUN mk-build-deps -r -i debian/control -t 'apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends'
+# To avoid constantly invalidating previous container layers, run the slow
+# dependency installation early and copy files (along with any changed files)
+# later
+COPY . .
+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
+ ${container_cmd} 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
+ container_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
+ ${container_cmd} 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:c:" 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}";;
+ c) container_cmd="${OPTARG}";;
+ :) die "missing argument: -${OPTARG}";;
+ \?) die "bad option: -${OPTARG}";;
+ esac
+done
+
+# Set default container command
+container_cmd="${container_cmd:-podman}"
+
+# Set default container command value if none set
+case "${container_cmd}" in
+ docker|podman) ;;
+ *) die "container command is expected to be one of 'docker' or 'podman'" ;;
+esac
+
+shift $((OPTIND - 1))
+case "${1:-test}" in
+ 'help') usage; exit 0;;
+ 'test') gbp_test; exit ${?};;
+ 'package') gbp_package; exit ${?};;
+ *) die "bad action: ${1}";;
+esac