diff options
author | Levente Polyak <anthraxx@archlinux.org> | 2022-12-17 01:51:15 +0100 |
---|---|---|
committer | Levente Polyak <anthraxx@archlinux.org> | 2023-05-19 22:27:13 +0200 |
commit | 5752488ef114513c8f75d753cf91d5b61dfa0660 (patch) | |
tree | 53b3fb27b343838efa3bcd70412cedc1c470d957 | |
parent | b9db6160a2547a57d19308776a25223eb2130b6b (diff) | |
download | devtools-5752488ef114513c8f75d753cf91d5b61dfa0660.tar.xz |
release: command to commit, tag and upload build artifacts
This is a smart and more convenient invocation of the classical
commitpkg and archrelease with auto-discovery for target repositories
and a shorthand option to directly call db-update.
-rw-r--r-- | contrib/completion/zsh/_devtools.in | 11 | ||||
-rw-r--r-- | doc/man/pkgctl-release.1.asciidoc | 49 | ||||
-rw-r--r-- | doc/man/pkgctl.1.asciidoc | 4 | ||||
-rw-r--r-- | src/lib/release.sh | 167 | ||||
-rw-r--r-- | src/lib/util/pacman.sh | 52 | ||||
-rw-r--r-- | src/pkgctl.in | 9 |
6 files changed, 292 insertions, 0 deletions
diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 62d9fea..2961f6f 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -59,6 +59,16 @@ _pkgctl_db_update_args=( '(-h --help)'{-h,--help}'[Display usage]' ) +_pkgctl_release_args=( + '(-m --message=)'{-m,--message=}"[Use the given <msg> as the commit message]:message:" + '(-r --repo=)'{-r,--repo=}"[Specify a target repository (disables auto-detection)]:repo:($_repos[*])" + '(-s --staging)'{-s,--staging}'[Release to the staging counterpart of the auto-detected repo]' + '(-t --testing)'{-t,--testing}'[Release to the testing counterpart of the auto-detected repo]' + '(-u --db-update)'{-u,--db-update}'[Automatically update the pacman database after uploading]' + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" @@ -205,6 +215,7 @@ _pkgctl_cmds=( "auth[Authenticate with services like GitLab]" "db[Pacman database modification for packge update, move etc]" "diff[Compare package files using different modes]" + "release[Release step to commit, tag and upload build artifacts]" "repo[Manage Git packaging repositories and their configuration]" ) diff --git a/doc/man/pkgctl-release.1.asciidoc b/doc/man/pkgctl-release.1.asciidoc new file mode 100644 index 0000000..c991db4 --- /dev/null +++ b/doc/man/pkgctl-release.1.asciidoc @@ -0,0 +1,49 @@ +pkgctl-release(1) +================= + +Name +---- +pkgctl-release - Release step to commit, tag and upload build artifacts + +Synopsis +-------- +pkgctl release [OPTIONS] [PATH...] + +Description +----------- + +Modified version controlled files will first be staged for commit, +afterwards a Git tag matching the pkgver will be created and finally +all build artifacts will be uploaded. + +By default the target pacman repository will be auto-detected by querying +the repo it is currently released in. When initially adding a new package +to the repositories, the target repo must be specified manually. + +Options +------- + +*-m, --message* 'MSG':: + Use the given <msg> as the commit message + +*-r, --repo* 'REPO':: + Specify a target repository (disables auto-detection) + +*-s, --staging*:: + Build against the staging counterpart of the auto-detected repo + +*-t, --testing*:: + Build against the testing counterpart of the auto-detected repo + +*-u, --db-update*:: + Automatically update the pacman database after uploading + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-db-update[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 93fed5b..8da5d19 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -26,6 +26,9 @@ pkgctl db:: pkgctl diff:: Compare package files using different modes +pkgctl release:: + Release step to commit, tag and upload build artifacts + pkgctl repo:: Manage Git packaging repositories and their configuration @@ -35,6 +38,7 @@ See Also linkman:pkgctl-auth[1] linkman:pkgctl-db[1] linkman:pkgctl-diff[1] +linkman:pkgctl-release[1] linkman:pkgctl-repo[1] include::include/footer.asciidoc[] diff --git a/src/lib/release.sh b/src/lib/release.sh new file mode 100644 index 0000000..aabbd35 --- /dev/null +++ b/src/lib/release.sh @@ -0,0 +1,167 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_RELEASE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_RELEASE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/db/update.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.sh +# shellcheck source=src/lib/util/pacman.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh +# shellcheck source=src/lib/valid-repos.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh + +source /usr/share/makepkg/util/util.sh + +set -e + + +pkgctl_release_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PATH]... + + Release step to commit, tag and upload build artifacts + + Modified version controlled files will first be staged for commit, + afterwards a Git tag matching the pkgver will be created and finally + all build artifacts will be uploaded. + + By default the target pacman repository will be auto-detected by querying + the repo it is currently released in. When initially adding a new package + to the repositories, the target repo must be specified manually. + + OPTIONS + -m, --message MSG Use the given <msg> as the commit message + -r, --repo REPO Specify a target repository (disables auto-detection) + -s, --staging Release to the staging counterpart of the auto-detected repo + -t, --testing Release to the testing counterpart of the auto-detected repo + -u, --db-update Automatically update the pacman database after uploading + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --repo core-testing --message 'libyay 0.42 rebuild' libfoo libbar + $ ${COMMAND} --staging --db-update libfoo +_EOF_ +} + +pkgctl_release_check_option_group() { + local option=$1 + local repo=$2 + local testing=$3 + local staging=$4 + if [[ -n "${repo}" ]] || (( testing )) || (( staging )); then + die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}" + exit 1 + fi + return 0 +} + +pkgctl_release() { + if (( $# < 1 )) && [[ ! -f PKGBUILD ]]; then + pkgctl_release_usage + exit 1 + fi + + local MESSAGE="" + local PKGBASES=() + local REPO="" + local TESTING=0 + local STAGING=0 + local DB_UPDATE=0 + + local path pkgbase pkgnames repo repos + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_release_usage + exit 0 + ;; + -m|--message) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MESSAGE=$2 + shift 2 + ;; + -r|--repo) + (( $# <= 1 )) && die "missing argument for %s" "$1" + pkgctl_release_check_option_group '--repo' "${REPO}" "${TESTING}" "${STAGING}" + REPO=$2 + shift 2 + ;; + -s|--staging) + pkgctl_release_check_option_group '--staging' "${REPO}" "${TESTING}" "${STAGING}" + STAGING=1 + shift + ;; + -t|--testing) + pkgctl_release_check_option_group '--testing' "${REPO}" "${TESTING}" "${STAGING}" + TESTING=1 + shift + ;; + -u|--db-update) + DB_UPDATE=1 + shift + ;; + -*) + die "invalid option: %s" "$1" + ;; + *) + PKGBASES+=("$@") + break + ;; + esac + done + + # Resolve package from current working directory + if (( 0 == ${#PKGBASES[@]} )); then + PKGBASES=("$PWD") + fi + + # Update pacman cache for auto-detection + if [[ -z ${REPO} ]]; then + update_pacman_repo_cache + # Check valid repos if not resolved dynamically + elif ! in_array "${REPO}" "${_repos[@]}"; then + die "Invalid repository target: %s" "${REPO}" + fi + + for path in "${PKGBASES[@]}"; do + pushd "${path}" >/dev/null + pkgbase=$(basename "${path}") + + if [[ -n ${REPO} ]]; then + repo=${REPO} + else + if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then + die 'Failed to get pacman repo' + fi + if [[ -z "${repo}" ]]; then + die 'Unknown repo, please specify --repo for new packages' + fi + fi + + if (( TESTING )); then + repo="${repo}-testing" + elif (( STAGING )); then + repo="${repo}-staging" + elif [[ $repo == core ]]; then + repo="${repo}-testing" + fi + + msg "Releasing ${pkgbase} to ${repo}" + commitpkg "${repo}" "${MESSAGE}" + + unset repo + popd >/dev/null + done + + if (( DB_UPDATE )); then + # shellcheck disable=2119 + pkgctl_db_update + fi +} diff --git a/src/lib/util/pacman.sh b/src/lib/util/pacman.sh new file mode 100644 index 0000000..f6c2d5f --- /dev/null +++ b/src/lib/util/pacman.sh @@ -0,0 +1,52 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_UTIL_PACMAN_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_UTIL_PACMAN_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +readonly _DEVTOOLS_PACMAN_CACHE_DIR=${XDG_CACHE_DIR:-$HOME/.cache}/devtools/pacman/db +readonly _DEVTOOLS_PACMAN_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/pacman.conf.d +readonly _DEVTOOLS_MAKEPKG_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/makepkg.conf.d + + +update_pacman_repo_cache() { + mkdir -p "${_DEVTOOLS_PACMAN_CACHE_DIR}" + msg "Updating pacman database cache" + lock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" + fakeroot -- pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \ + --dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \ + -Sy + lock_close 10 +} + +get_pacman_repo_from_pkgbuild() { + local path=${1:-PKGBUILD} + + # shellcheck source=contrib/makepkg/PKGBUILD.proto + mapfile -t pkgnames < <(source "${path}"; printf "%s\n" "${pkgname[@]}") + + if (( ${#pkgnames[@]} == 0 )); then + die 'Failed to get pkgname from %s' "${path}" + return + fi + + slock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" + mapfile -t repos < <(pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \ + --dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \ + -S \ + --print \ + --print-format '%n %r' \ + "${pkgnames[0]}" | grep -E "^${pkgnames[0]} " | awk '{print $2}' + ) + lock_close 10 + + printf "%s" "${repos[0]}" +} diff --git a/src/pkgctl.in b/src/pkgctl.in index d9e1b4c..47409de 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -22,6 +22,7 @@ usage() { auth Authenticate with services like GitLab db Pacman database modification for packge update, move etc diff Compare package files using different modes + release Release step to commit, tag and upload build artifacts repo Manage Git packaging repositories and their configuration OPTIONS @@ -75,6 +76,14 @@ while (( $# )); do diffpkg "$@" exit 0 ;; + release) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/release.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh + pkgctl_release "$@" + exit 0 + ;; *) die "invalid command: %s" "$1" ;; |