qusal/scripts/spec-gen.sh
Ben Grande fc22726ee8
feat: build and sign RPM packages
Passing files to Dom0 is always dangerous:

- Passing a git repository is dangerous as it can have ignored modified
  files and signature verification will pass.
- Passing an archive is troublesome for updates.
- Passing an RPM package depends on the RPM verification to be correct,
  some times it is not.
- Passing a RPM repository definition is less troublesome for the user,
  as it is a small file to verify the contents and update mechanism is
  via the package manager. Trust in RPM verification is still required.

Many improvements were made to the build scripts:

- requires-program: Single function to check if program is installed;
- spec-get: Sort project names for the usage message;
- spec-get: Only running commands that are necessary;
- spec-get: Fix empty summary when readme has copyright header;
- spec-gen: Fix grep warning of escaped symbol;
- spec-build: Sign RPM and verify signature;
- spec-build: Only lint the first SPEC for faster runtime;
- yumrepo-gen: Generate a local yum repository with signed metadata;
- qubesbuilder-gen: Generate a .qubesbuilder based on tracked projects;
- release: Build, sign and push all RPMs to repository.

Goal is to be able to build with qubes-builderv2 Qubes Executor.

For: https://github.com/ben-grande/qusal/issues/37
2024-06-12 14:44:04 +02:00

95 lines
2.8 KiB
Bash
Executable File

#!/bin/sh
## SPDX-FileCopyrightText: 2023 Benjamin Grande M. S. <ben.grande.b@gmail.com>
##
## SPDX-License-Identifier: AGPL-3.0-or-later
set -eu
usage(){
echo "Usage: ${0##*/} PROJECT [PROJECT ...]"
}
# get_scriptlet scriptlet-action
# [pre|post]-[install|upgrade], [pre|post]un-[uninstall|upgrade]
## Get scriptlet command, else fail safe.
get_scriptlet(){
scriptlet="$1"
sed -n "/^<\!-- pkg:begin:${scriptlet} -->$/,/^<\!-- pkg:end:${scriptlet} -->$/p" \
"${readme}" | sed '/^```.*/d;/^<\!-- pkg:/d;s/^sudo //' || echo "true"
}
get_spec(){
"${spec_get}" "${project}" "${1}"
}
gen_spec(){
project="${1}"
## Test if a standard option works without error.
get_spec name >/dev/null
group="$(get_spec group)"
template="rpm_spec/template/template.spec"
target="rpm_spec/${group}-${project}.spec"
## Escape multiline strings for sed
escaped_key(){
echo "${1}" | sed ':a;N;$!ba;s/\n/\\n /g' | sed 's/\$/\\$/'
}
readme="$(get_spec readme)"
pre_install="$(escaped_key "$(get_scriptlet pre-install)")"
pre_upgrade="$(escaped_key "$(get_scriptlet pre-upgrade)")"
post_install="$(escaped_key "$(get_scriptlet post-install)")"
post_upgrade="$(escaped_key "$(get_scriptlet post-upgrade)")"
preun_uninstall="$(escaped_key "$(get_scriptlet preun-uninstall)")"
preun_upgrade="$(escaped_key "$(get_scriptlet preun-upgrade)")"
postun_uninstall="$(escaped_key "$(get_scriptlet postun-uninstall)")"
postun_upgrade="$(escaped_key "$(get_scriptlet postun-upgrade)")"
version="$(get_spec version)"
changelog="$(get_spec changelog)"
requires="$(get_spec requires)"
sed \
-e "s/@PRE_INSTALL@/${pre_install}/" \
-e "s/@PRE_UPGRADE@/${pre_upgrade}/" \
-e "s/@POST_INSTALL@/${post_install}/" \
-e "s/@POST_UPGRADE@/${post_upgrade}/" \
-e "s/@PREUN_UNINSTALL@/${preun_uninstall}/" \
-e "s/@PREUN_UPGRADE@/${preun_upgrade}/" \
-e "s/@POSTUN_UNINSTALL@/${postun_uninstall}/" \
-e "s/@POSTUN_UPGRADE@/${postun_upgrade}/" \
-e "s/@VERSION@/${version}/" \
-e "s/@PROJECT@/${project}/" \
-e "/@CHANGELOG@/d" \
"${template}" | tee "${target}" >/dev/null
requires_key=""
for r in $(printf %s"${requires}" | tr " " "\n" | sort -u); do
requires_key="${requires_key}\nRequires: ${group}-${r}"
done
sed -i "s/@REQUIRES@/${requires_key}/" "${target}" >/dev/null
echo "${changelog}" | tee -a "${target}" >/dev/null
}
case "${1-}" in
-h|--?help) usage; exit 1;;
esac
command -v git >/dev/null || { echo "Missing program: git" >&2; exit 1; }
cd "$(git rev-parse --show-toplevel)"
spec_get="./scripts/spec-get.sh"
if test -z "${1-}"; then
# shellcheck disable=SC2046
set -- $(find salt/ -mindepth 1 -maxdepth 1 -type d -printf '%f\n' \
| sort -d | tr "\n" " ")
fi
for p in "$@"; do
gen_spec "${p}"
done