[LTP] [PATCH v6 2/4] ci: add patchwork communication script
pvorel
pvorel@suse.de
Tue Apr 15 15:48:33 CEST 2025
Hi Andrea,
TL;DR:
With fixed == and curl pipe redirect, you may add:
Reviewed-by: Petr Vorel <pvorel@suse.cz>
More info below.
> ---
> ci/tools/patchwork.sh | 169
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 169 insertions(+)
>
> diff --git a/ci/tools/patchwork.sh b/ci/tools/patchwork.sh
> new file mode 100755
> index
> 0000000000000000000000000000000000000000..bef6998b6168714e0cfaef443a4573017440bb2d
> --- /dev/null
> +++ b/ci/tools/patchwork.sh
> @@ -0,0 +1,169 @@
> +#!/bin/sh -x
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# Shell script to communicate with Patchwork via REST API.
> +# It has been mainly created for CI purposes, but it can be used in
> the shell
> +# by satisfying minimum requirements.
> +#
> +# Copyright (c) 2025 Andrea Cervesato <andrea.cervesato@suse.com>
> +
> +PATCHWORK_URL="${PATCHWORK_URL:-https://patchwork.ozlabs.org}"
> +PATCHWORK_SINCE="${PATCHWORK_SINCE:-3600}"
> +
> +command_exists() {
Can you please add before merge?
local cmd
> + for cmd in "$@"; do
> + if ! command -v "$cmd" >/dev/null 2>&1; then
> + echo "'$1' must be present in the system" >&2
> + exit 1
> + fi
> + done
> +}
> +
> +command_exists "curl" "jq"
> +
> +fetch_series() {
> + local current_time=$(date +%s)
> + local since_time=$(expr $current_time - $PATCHWORK_SINCE)
> + local date=$(date -u -d @$since_time +"%Y-%m-%dT%H:%M:%SZ")
> +
> + curl -k -G "$PATCHWORK_URL/api/events/" \
> + --data "category=series-completed" \
> + --data "project=ltp" \
> + --data "state=new" \
> + --data "since=$date" \
> + --data "archive=no" |
> + jq -r '.[] |
> "\(.payload.series.id):\(.payload.series.mbox)"'
> +
> + [ $? -eq 0 ] || exit 1
FYI $? holds exit code of the last member of pipe, 'jq -r ...' in this
case.
I guess you'd prefer to check curl exit code, right?
You have 2 options:
1) Redirect curl with '-o log', and call jq after $? evaluation.
2) Depend on bash and use ${PIPESTATUS[0]} (e.g. $PIPESTATUS array).
NOTE: that really requires /bin/bash shebang (e.g. not working on dash
and busybox sh, thus CI will depend on bash), also will not work on zsh
which uses $pipestatus array (lower case) :(. We prefer to avoid bash
(unlike kernel developers) for a good reason (bash incompatibility
between versions, need to install bash in container, also if arrays are
needed it's a question whether use shell scripting), but it's mainly due
the need tests (LTP shell API and tests) to be portable, it could be
used in tools (with /bin/bash shebang).
> +}
> +
> +get_patches() {
> + local series_id="$1"
> +
> + curl -k -G "$PATCHWORK_URL/api/patches/" \
> + --data "project=ltp" \
> + --data "series=$series_id" |
> + jq -r '.[] | "\(.id)"'
> +
> + [ $? -eq 0 ] || exit 1
> +}
> +
> +verify_token_exists() {
> + if [ -z "$PATCHWORK_TOKEN" ]; then
> + echo "For this feature you need \$PATCHWORK_TOKEN"
> + exit 1
> + fi
> +}
> +
> +set_patch_state() {
> + local patch_id="$1"
> + local state="$2"
> +
> + verify_token_exists
> +
> + curl -k -X PATCH \
> + -H "Authorization: Token $PATCHWORK_TOKEN" \
> + -F "state=$state" \
> + "$PATCHWORK_URL/api/patches/$patch_id/"
> +
> + [ $? -eq 0 ] || exit 1
> +}
> +
> +set_series_state() {
> + local series_id="$1"
> + local state="$2"
> +
> + get_patches "$series_id" | while IFS= read -r patch_id; do
> + [ "$patch_id" ] && set_patch_state "$patch_id"
> "$state"
FYI if you ever wish to use '-e' in a script, construct [ ... ] && ...
will be broken with it.
It would have to be [ ... ] || ... (or use if ...; then ...; fi).
> + done
> +}
> +
> +get_checks() {
> + local patch_id="$1"
> +
> + curl -k -G "$PATCHWORK_URL/api/patches/$patch_id/checks/" |
> + jq -r '.[] | "\(.id)"'
> +
> + [ $? -eq 0 ] || exit 1
> +}
> +
> +already_tested() {
> + local series_id="$1"
> +
> + get_patches "$series_id" | while IFS= read -r patch_id; do
> + [ "$patch_id" ] || continue
> +
> + get_checks "$patch_id" | while IFS= read -r check_id;
> do
> + if [ -n "$check_id" ]; then
> + echo "$check_id"
> + return
> + fi
> + done
> + done
> +}
> +
> +verify_new_patches() {
> + local tmp=$(mktemp -d)
> + local output="$tmp/series_ids.txt"
> +
> + echo -n '' >"$output"
FYI echo switches are known to have non-portable edge cases, which
printf does not have, but this works (ok to use). Using printf would be
simpler:
printf >"$output"
> +
> + fetch_series | while IFS=: read -r series_id series_mbox; do
> + [ "$series_id" ] || continue
> +
> + tested=$(already_tested "$series_id")
> + [ "$tested" ] && continue
> +
> + echo "$series_id|$series_mbox" >>"$output"
> + done
> +
> + cat "$output"
> +}
> +
> +send_results() {
> + local series_id="$1"
> + local target_url="$2"
> +
> + verify_token_exists
> +
> + local context=$(echo "$3" | sed 's/:/_/g; s/\//-/g; s/\./-/g')
> +
> + [ "$CC" ] && context="${context}_${CC}"
> + [ "$ARCH" ] && context="${context}_${ARCH}"
> +
> + local result="$4"
> + [ "$result" == "cancelled" ] && return
== is a bashism, please use =
> +
> + local state="fail"
> + [ "$result" == "success" ] && state="success"
And here as well.
We have checkbashisms part of make check, but that's for our LTP build
system directories, here you must call it directly:
$ checkbashisms ci/tools/patchwork.sh
possible bashism in ci/tools/patchwork.sh line 135 (should be 'b = a'):
[ "$result" == "cancelled" ] && return
possible bashism in ci/tools/patchwork.sh line 138 (should be 'b = a'):
[ "$result" == "success" ] && state="success"
> +
> + get_patches "$series_id" | while IFS= read -r patch_id; do
> + [ "$patch_id" ] || continue
> +
> + curl -k -X POST \
> + -H "Authorization: Token $PATCHWORK_TOKEN" \
> + -F "state=$state" \
> + -F "context=$context" \
> + -F "target_url=$target_url" \
> + -F "description=$result" \
> + "$PATCHWORK_URL/api/patches/$patch_id/checks/"
> +
> + [ $? -eq 0 ] && exit 1
> + done
> +}
> +
> +case "$1" in
> +state)
I see you don't want to support running whole script in once for
debugging.
Using '' would allow it (up to you of course, as most of comments):
''|state)
Kind regards,
Petr
> + set_series_state "$2" "$3"
> + ;;
> +check)
> + send_results "$2" "$3" "$4" "$5"
> + ;;
> +verify)
> + verify_new_patches
> + ;;
> +*)
> + echo "Available commands: state, check, verify"
> + exit 1
> + ;;
> +esac
>
> --
> 2.43.0
More information about the ltp
mailing list