* [RFC v2 0/3] Add a recheck framework to pw-ci @ 2023-11-07 20:31 Aaron Conole 2023-11-07 20:31 ` [RFC v2 1/3] pw_mon: improve command line options Aaron Conole ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Aaron Conole @ 2023-11-07 20:31 UTC (permalink / raw) To: ci Cc: Michael Santana, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara This allows users to send repsonse emails to patches and force rebuilds of the workflow in github actions. This has been tested with the following: for recheck in $(./recheck_tool --pw-project=dpdk \ --pw-instance=patches.dpdk.org \ --filter=github-robot --state=1 | \ jq -rc '.rechecks[]'); do ./github_restart --pw-project=dpdk --pw-instance=patches.dpdk.org \ --series-id=$(echo "$recheck" | \ jq -rc '.series_id') \ --repository=ovsrobot/dpdk \ --sha=$(echo "$recheck" | jq -rc '.sha') \ --github-token=XXXXXXXX done And succesffully rebuilt 6457922075 from series 29774 which does have a recheck-request (we used the iol-unit-amd64-testing filter to do the test). To be added is a way to filter on specific workflows so we don't restart all workflows associated with the run for those projects which have more than one workflow. This can be combined with a second call of the recheck tool to advance the state. When the series id is provided, the tool will update the gap_sync column for the specific row and future calls to github_monitor script will then scan the new run. Aaron Conole (3): pw_mon: improve command line options recheck: Add a recheck parser for patchwork comments github: add a tool for restarting checks github_restart | 141 +++++++++++++++++++++++++++++++++++++++++++++++ pw_mon | 123 ++++++++++++++++++++++++++++++++++++----- recheck_tool | 100 +++++++++++++++++++++++++++++++++ series_db_lib.sh | 80 ++++++++++++++++++++++++++- 4 files changed, 428 insertions(+), 16 deletions(-) create mode 100755 github_restart create mode 100755 recheck_tool -- 2.41.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC v2 1/3] pw_mon: improve command line options 2023-11-07 20:31 [RFC v2 0/3] Add a recheck framework to pw-ci Aaron Conole @ 2023-11-07 20:31 ` Aaron Conole 2023-11-17 16:26 ` Michael Santana 2023-11-07 20:31 ` [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments Aaron Conole 2023-11-07 20:31 ` [RFC v2 3/3] github: add a tool for restarting checks Aaron Conole 2 siblings, 1 reply; 13+ messages in thread From: Aaron Conole @ 2023-11-07 20:31 UTC (permalink / raw) To: ci Cc: Michael Santana, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara In the future, we'll use this to add support for passing opts into some parts of pw_mon. Signed-off-by: Aaron Conole <aconole@redhat.com> --- pw_mon | 65 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/pw_mon b/pw_mon index 28feb8b..da4b9a9 100755 --- a/pw_mon +++ b/pw_mon @@ -21,34 +21,71 @@ [ -f "${HOME}/.pwmon-rc" ] && source "${HOME}/.pwmon-rc" -if [ "$1" != "" ]; then - pw_project="$1" - shift +if [ "$1" != "" ]; then + if ! echo "$1" | grep -q -s -E ^-- ; then + pw_project="$1" + shift + fi fi if [ "$1" != "" ]; then - pw_instance="$1" - shift -fi - -if [ "X$pw_instance" == "X" -o "X$pw_project" == "X" ]; then - echo "ERROR: Patchwork instance and project are unset." - echo "Please setup ${HOME}/.pwmon-rc and set pw_project " - echo "(or pass it as an argument)." - echo "Also either setup pw_instance or pass it as an argument." - exit 1 + if ! echo "$1" | grep -q -s -E ^-- ; then + pw_instance="$1" + shift + fi fi userpw="" if [ "$1" != "" ]; then - pw_credential="$1" + if ! echo "$1" | grep -q -s -E ^-- ; then + pw_credential="$1" + shift + fi fi + +while [ "$1" != "" ]; do + if echo "$1" | grep -q -s -E ^--pw-project= ; then + pw_project=$(echo "$1" | sed s/^--pw-project=//) + shift + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) + shift + elif echo "$1" | grep -q -s -E ^--pw-credentials= ; then + pw_credential=$(echo "$1" | sed s/^--pw-credentials=//) + shift + elif echo "$1" | grep -E ^--help >/dev/null 2>&1; then + echo "patchwork monitor script" + echo "$0: args" + echo "Required if not set in ~/.pwmon-rc file:" + echo " proj|--pw-project=<proj> Project name" + echo " instance|--pw-instance=<inst url> URL for pw" + echo "" + echo "Options:" + echo " --pw-credentials=u:p Sets user / password for web client" + echo " --add-filter-recheck=filter Adds a filter to flag that a recheck needs to be done" + echo "" + exit 0 + else + echo "Unknown option: '$1'" + echo "Rerun with --help for details" + exit 1 + fi +done + if [ "X$pw_credential" != "X" ]; then userpw="-u \"${pw_credential}\"" fi +if [ "X$pw_instance" == "X" -o "X$pw_project" == "X" ]; then + echo "ERROR: Patchwork instance and project are unset." + echo "Please setup ${HOME}/.pwmon-rc and set pw_project " + echo "(or pass it as an argument)." + echo "Also either setup pw_instance or pass it as an argument." + exit 1 +fi + source $(dirname $0)/series_db_lib.sh function emit_series() { -- 2.41.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 1/3] pw_mon: improve command line options 2023-11-07 20:31 ` [RFC v2 1/3] pw_mon: improve command line options Aaron Conole @ 2023-11-17 16:26 ` Michael Santana 2023-11-17 19:28 ` Aaron Conole 0 siblings, 1 reply; 13+ messages in thread From: Michael Santana @ 2023-11-17 16:26 UTC (permalink / raw) To: Aaron Conole Cc: ci, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara On Tue, Nov 7, 2023 at 3:32 PM Aaron Conole <aconole@redhat.com> wrote: > > In the future, we'll use this to add support for passing opts into some parts > of pw_mon. > > Signed-off-by: Aaron Conole <aconole@redhat.com> Acked-by: Michael Santana <msantana@redhat.com> > --- > pw_mon | 65 +++++++++++++++++++++++++++++++++++++++++++++------------- > 1 file changed, 51 insertions(+), 14 deletions(-) > > diff --git a/pw_mon b/pw_mon > index 28feb8b..da4b9a9 100755 > --- a/pw_mon > +++ b/pw_mon > @@ -21,34 +21,71 @@ > > [ -f "${HOME}/.pwmon-rc" ] && source "${HOME}/.pwmon-rc" > > -if [ "$1" != "" ]; then > - pw_project="$1" > - shift > +if [ "$1" != "" ]; then > + if ! echo "$1" | grep -q -s -E ^-- ; then The missing quotes give me OCD, but I'll let it pass :) It is technically correct apparently. It worked when I tested it. I guess I am so used to using grep with quotes that I had never considered that there was a whole world where people use grep without quotes :P > + pw_project="$1" > + shift > + fi > fi > > if [ "$1" != "" ]; then > - pw_instance="$1" > - shift > -fi > - > -if [ "X$pw_instance" == "X" -o "X$pw_project" == "X" ]; then > - echo "ERROR: Patchwork instance and project are unset." > - echo "Please setup ${HOME}/.pwmon-rc and set pw_project " > - echo "(or pass it as an argument)." > - echo "Also either setup pw_instance or pass it as an argument." > - exit 1 > + if ! echo "$1" | grep -q -s -E ^-- ; then > + pw_instance="$1" > + shift > + fi > fi > > userpw="" > > if [ "$1" != "" ]; then > - pw_credential="$1" > + if ! echo "$1" | grep -q -s -E ^-- ; then > + pw_credential="$1" > + shift > + fi > fi > > + > +while [ "$1" != "" ]; do > + if echo "$1" | grep -q -s -E ^--pw-project= ; then > + pw_project=$(echo "$1" | sed s/^--pw-project=//) > + shift > + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then > + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) > + shift > + elif echo "$1" | grep -q -s -E ^--pw-credentials= ; then > + pw_credential=$(echo "$1" | sed s/^--pw-credentials=//) > + shift > + elif echo "$1" | grep -E ^--help >/dev/null 2>&1; then > + echo "patchwork monitor script" > + echo "$0: args" > + echo "Required if not set in ~/.pwmon-rc file:" > + echo " proj|--pw-project=<proj> Project name" > + echo " instance|--pw-instance=<inst url> URL for pw" > + echo "" > + echo "Options:" > + echo " --pw-credentials=u:p Sets user / password for web client" > + echo " --add-filter-recheck=filter Adds a filter to flag that a recheck needs to be done" > + echo "" > + exit 0 > + else > + echo "Unknown option: '$1'" > + echo "Rerun with --help for details" > + exit 1 > + fi > +done > + > if [ "X$pw_credential" != "X" ]; then > userpw="-u \"${pw_credential}\"" > fi > > +if [ "X$pw_instance" == "X" -o "X$pw_project" == "X" ]; then > + echo "ERROR: Patchwork instance and project are unset." > + echo "Please setup ${HOME}/.pwmon-rc and set pw_project " > + echo "(or pass it as an argument)." > + echo "Also either setup pw_instance or pass it as an argument." > + exit 1 > +fi > + > source $(dirname $0)/series_db_lib.sh > > function emit_series() { > -- > 2.41.0 > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 1/3] pw_mon: improve command line options 2023-11-17 16:26 ` Michael Santana @ 2023-11-17 19:28 ` Aaron Conole 0 siblings, 0 replies; 13+ messages in thread From: Aaron Conole @ 2023-11-17 19:28 UTC (permalink / raw) To: Michael Santana Cc: ci, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara Michael Santana <msantana@redhat.com> writes: > On Tue, Nov 7, 2023 at 3:32 PM Aaron Conole <aconole@redhat.com> wrote: >> >> In the future, we'll use this to add support for passing opts into some parts >> of pw_mon. >> >> Signed-off-by: Aaron Conole <aconole@redhat.com> > Acked-by: Michael Santana <msantana@redhat.com> Thanks >> --- >> pw_mon | 65 +++++++++++++++++++++++++++++++++++++++++++++------------- >> 1 file changed, 51 insertions(+), 14 deletions(-) >> >> diff --git a/pw_mon b/pw_mon >> index 28feb8b..da4b9a9 100755 >> --- a/pw_mon >> +++ b/pw_mon >> @@ -21,34 +21,71 @@ >> >> [ -f "${HOME}/.pwmon-rc" ] && source "${HOME}/.pwmon-rc" >> >> -if [ "$1" != "" ]; then >> - pw_project="$1" >> - shift >> +if [ "$1" != "" ]; then >> + if ! echo "$1" | grep -q -s -E ^-- ; then > The missing quotes give me OCD, but I'll let it pass :) > > It is technically correct apparently. It worked when I tested it. I > guess I am so used to using grep with quotes that I had never > considered that there was a whole world where people use grep without > quotes :P > >> + pw_project="$1" >> + shift >> + fi >> fi >> >> if [ "$1" != "" ]; then >> - pw_instance="$1" >> - shift >> -fi >> - >> -if [ "X$pw_instance" == "X" -o "X$pw_project" == "X" ]; then >> - echo "ERROR: Patchwork instance and project are unset." >> - echo "Please setup ${HOME}/.pwmon-rc and set pw_project " >> - echo "(or pass it as an argument)." >> - echo "Also either setup pw_instance or pass it as an argument." >> - exit 1 >> + if ! echo "$1" | grep -q -s -E ^-- ; then >> + pw_instance="$1" >> + shift >> + fi >> fi >> >> userpw="" >> >> if [ "$1" != "" ]; then >> - pw_credential="$1" >> + if ! echo "$1" | grep -q -s -E ^-- ; then >> + pw_credential="$1" >> + shift >> + fi >> fi >> >> + >> +while [ "$1" != "" ]; do >> + if echo "$1" | grep -q -s -E ^--pw-project= ; then >> + pw_project=$(echo "$1" | sed s/^--pw-project=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then >> + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--pw-credentials= ; then >> + pw_credential=$(echo "$1" | sed s/^--pw-credentials=//) >> + shift >> + elif echo "$1" | grep -E ^--help >/dev/null 2>&1; then >> + echo "patchwork monitor script" >> + echo "$0: args" >> + echo "Required if not set in ~/.pwmon-rc file:" >> + echo " proj|--pw-project=<proj> Project name" >> + echo " instance|--pw-instance=<inst url> URL for pw" >> + echo "" >> + echo "Options:" >> + echo " --pw-credentials=u:p Sets user / password for web client" >> + echo " --add-filter-recheck=filter Adds a filter to flag that a recheck needs to be done" >> + echo "" >> + exit 0 >> + else >> + echo "Unknown option: '$1'" >> + echo "Rerun with --help for details" >> + exit 1 >> + fi >> +done >> + >> if [ "X$pw_credential" != "X" ]; then >> userpw="-u \"${pw_credential}\"" >> fi >> >> +if [ "X$pw_instance" == "X" -o "X$pw_project" == "X" ]; then >> + echo "ERROR: Patchwork instance and project are unset." >> + echo "Please setup ${HOME}/.pwmon-rc and set pw_project " >> + echo "(or pass it as an argument)." >> + echo "Also either setup pw_instance or pass it as an argument." >> + exit 1 >> +fi >> + >> source $(dirname $0)/series_db_lib.sh >> >> function emit_series() { >> -- >> 2.41.0 >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments 2023-11-07 20:31 [RFC v2 0/3] Add a recheck framework to pw-ci Aaron Conole 2023-11-07 20:31 ` [RFC v2 1/3] pw_mon: improve command line options Aaron Conole @ 2023-11-07 20:31 ` Aaron Conole 2023-11-09 20:45 ` Dumitru Ceara 2023-11-17 16:35 ` Michael Santana 2023-11-07 20:31 ` [RFC v2 3/3] github: add a tool for restarting checks Aaron Conole 2 siblings, 2 replies; 13+ messages in thread From: Aaron Conole @ 2023-11-07 20:31 UTC (permalink / raw) To: ci Cc: Michael Santana, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara Add a recheck parsing tool that will allow for labs to build a recheck workflow based on specific recheck labels and projects, with an associated state machine and querying interface. The output of the recheck parsing tool is json and can be fed to jq or other json parsing utilities for better field support. Signed-off-by: Aaron Conole <aconole@redhat.com> --- pw_mon | 58 ++++++++++++++++++++++++++- recheck_tool | 100 +++++++++++++++++++++++++++++++++++++++++++++++ series_db_lib.sh | 64 +++++++++++++++++++++++++++++- 3 files changed, 220 insertions(+), 2 deletions(-) create mode 100755 recheck_tool diff --git a/pw_mon b/pw_mon index da4b9a9..29a9cb4 100755 --- a/pw_mon +++ b/pw_mon @@ -1,6 +1,6 @@ #!/bin/sh # SPDX-Identifier: gpl-2.0-or-later -# Copyright (C) 2018, Red Hat, Inc. +# Copyright (C) 2018-2023 Red Hat, Inc. # # Monitors a project on a patchwork instance for new series submissions # Records the submissions in the series database (and emits them on the @@ -44,6 +44,7 @@ if [ "$1" != "" ]; then fi fi +recheck_filter="" while [ "$1" != "" ]; do if echo "$1" | grep -q -s -E ^--pw-project= ; then @@ -67,6 +68,10 @@ while [ "$1" != "" ]; do echo " --add-filter-recheck=filter Adds a filter to flag that a recheck needs to be done" echo "" exit 0 + elif echo "$1" | grep -q -s -E ^--add-filter-recheck=; then + filter_str=$(echo "$1" | sed s/--add-filter-recheck=//) + recheck_filter="$filter_str $recheck_filter" + shift else echo "Unknown option: '$1'" echo "Rerun with --help for details" @@ -191,7 +196,58 @@ function check_superseded_series() { done } +function run_recheck() { + local recheck_list=$(echo "$7" | sed -e 's/^Recheck-request: // ' -e 's/,/ /g') + + for filter in $recheck_filter; do + for check in $recheck_list; do + if [ "$filter" == "$check" ]; then + insert_recheck_request_if_needed "$1" "$3" "$8" "$check" "$2" "$9" + fi + done + done +} + +function check_patch_for_retest_request() { + local patch_url="$1" + + local patch_json=$(curl -s "$userpw" "$patch_url") + local patch_comments_url=$(echo "$patch_json" | jq -rc '.comments') + local patch_id=$(echo "$patch_json" | jq -rc '.id') + if [ "Xnull" != "X$patch_comments_url" ]; then + local comments_json=$(curl -s "$userpw" "$patch_comments_url") + + local seq_end=$(echo "$comments_json" | jq -rc 'length') + if [ "$seq_end" -a $seq_end -gt 0 ]; then + seq_end=$((seq_end-1)) + for comment_id in $(seq 0 $seq_end); do + local recheck_requested=$(echo "$comments_json" | jq -rc ".[$comment_id].content" | grep "^Recheck-request: ") + if [ "X$recheck_requested" != "X" ]; then + local msgid=$(echo "$comments_json" | jq -rc ".[$comment_id].msgid") + run_recheck "$pw_instance" "$series_id" "$project" "$url" "$repo" "$branchname" "$recheck_requested" "$msgid" "$patch_id" + fi + done + fi + fi +} + +function check_series_needs_retest() { + local pw_instance="$1" + + series_get_active_branches "$pw_instance" | while IFS=\| read -r series_id project url repo branchname; do + local patch_comments_url=$(curl -s "$userpw" "$url" | jq -rc '.patches[] | .url') + + for patch in $patch_comments_url; do + check_patch_for_retest_request $patch + done + done +} + check_undownloaded_series "$pw_instance" "$pw_project" check_completed_series "$pw_instance" "$pw_project" check_new_series "$pw_instance" "$pw_project" check_superseded_series "$pw_instance" + +# check for retest requests after a series is still passing all the +# checks above +check_series_needs_retest "$pw_instance" diff --git a/recheck_tool b/recheck_tool new file mode 100755 index 0000000..98031a9 --- /dev/null +++ b/recheck_tool @@ -0,0 +1,100 @@ +#!/bin/sh +# SPDX-Identifier: gpl-2.0-or-later +# Copyright (C) 2023 Red Hat, Inc. +# +# Licensed under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. You may obtain a copy of the +# license at +# +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +mode="select" + +while [ "$1" != "" ]; do + if echo "$1" | grep -q -s -E ^--help ; then + echo "recheck / retest state machine script" + echo "" + echo "$0:" + echo " --pw-project=<proj>: Patchwork project." + echo " --pw-instance=<inst>: Patchwork instance." + echo " --filter=<str>: Job / request for recheck." + echo " --state=<0..>: Resync state ID." + echo " --msgid=<msgid>: Message ID to select." + echo " --update: Set tool in update mode" + echo " --new-state=<0..>: New state ID to set" + echo " --series-id=<..>: Series ID" + echo "" + echo "Will spit out a parsable json for each db line when selecting" + exit 0 + elif echo "$1" | grep -q -s -E ^--pw-project= ; then + pw_project=$(echo "$1" | sed s/^--pw-project=//) + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) + elif echo "$1" | grep -q -s -E ^--filter= ; then + filter=$(echo "$1" | sed s/^--filter=//) + elif echo "$1" | grep -q -s -E ^--state= ; then + recheck_state=$(echo "$1" | sed s/^--state=//) + elif echo "$1" | grep -q -s -E ^--msgid= ; then + message_id=$(echo "$1" | sed s/^--msgid=//) + elif echo "$1" | grep -q -s -E ^--update ; then + mode="update" + elif echo "$1" | grep -q -s -E ^--new-state= ; then + new_recheck_state=$(echo "$1" | sed s/^--new-state=//) + elif echo "$1" | grep -q -s -E ^--series-id= ; then + series_id=$(echo "$1" | sed s/^--series-id=//) + else + echo "Unknown option: '$1'" + echo "Rerun with --help for details" + exit 1 + fi + shift +done + +source $(dirname $0)/series_db_lib.sh + +if [ "$mode" == "select" ]; then + echo -n "{\"rechecks\":[" + printed="" + for request in $(get_recheck_requests_by_project "$pw_instance" \ + "$pw_project" \ + "$recheck_state" \ + "$filter"); do + message_id=$(echo $request | cut -d\| -f1) + series_id=$(echo $request | cut -d\| -f2) + patch_id=$(echo $request | cut -d\| -f3) + + sha=$(get_sha_for_series_id_and_patch "$series_id" "$patch_id" \ + "$pw_instance") + echo -n "$printed{\"pw_instance\":\"$pw_instance\",\"series_id\":$series_id,\"patch_id\":$patch_id,\"sha\":\"$sha\",\"msg_id\":\"$message_id\",\"state\":\"$recheck_state\",\"requested\":\"$filter\"}" + printed="," + done + echo "]}" +elif [ "$mode" == "update" ]; then + if [ "X$new_recheck_state" == "X" -o "X$series_id" == "X" ]; then + echo "Need to set a series-id and a new recheck state when updating." + exit 1 + fi + + request=$(get_recheck_request "$pw_instance" "$pw_project" "$message_id" \ + "$filter" "$series_id" "$recheck_state") + if [ "X$request" == "X" ]; then + echo "{\"result\":\"notfound\"}" + exit 0 + fi + + set_recheck_request_state "$pw_instance" "$pw_project" "$message_id" \ + "$filter" "$series_id" "$new_recheck_state" + + echo "{\"result\":\"executed\",\"recheck\":{\"pw_instance\": \"$pw_instance\", \"series_id\":$series_id, \"msg_id\":\"$message_id\", \"state\":\"$new_recheck_state\", \"requested\": \"$filter\"}}" +else + echo "Unknown state: $mode" + exit 1 +fi + diff --git a/series_db_lib.sh b/series_db_lib.sh index 6c2d98e..ca33c1f 100644 --- a/series_db_lib.sh +++ b/series_db_lib.sh @@ -1,6 +1,6 @@ #!/bin/sh # SPDX-Identifier: gpl-2.0-or-later -# Copyright (C) 2018,2019 Red Hat, Inc. +# Copyright (C) 2018-2023 Red Hat, Inc. # # Licensed under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or @@ -114,6 +114,22 @@ EOF run_db_command "INSERT INTO series_schema_version(id) values (7);" fi + run_db_command "select * from series_schema_version;" | egrep '^8$' > /dev/null 2>&1 + if [ $? -eq 1 ]; then + sqlite3 ${HOME}/.series-db <<EOF +CREATE TABLE recheck_requests ( +recheck_id INTEGER, +recheck_message_id STRING, +recheck_requested_by STRING, +recheck_series STRING, +recheck_patch INTEGER, +patchwork_instance STRING, +patchwork_project STRING, +recheck_sync INTEGER +); +EOF + run_db_command "INSERT INTO series_schema_version(id) values (8);" + fi } function series_db_exists() { @@ -390,3 +406,49 @@ function get_patch_id_by_series_id_and_sha() { echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute } + +function get_recheck_requests_by_project() { + local recheck_instance="$1" + local recheck_project="$2" + local recheck_state="$3" + local recheck_requested_by="$4" + + series_db_exists + + echo "select recheck_message_id,recheck_series,recheck_patch from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_sync=$recheck_state and recheck_requested_by=\"$recheck_requested_by\";" | series_db_execute +} + +function insert_recheck_request_if_needed() { + local recheck_instance="$1" + local recheck_project="$2" + local recheck_msgid="$3" + local recheck_requested_by="$4" + local recheck_series="$5" + local recheck_patch="$6" + + if ! echo "select * from recheck_requests where recheck_message_id=\"$recheck_msgid\";" | series_db_execute | grep $recheck_msgid >/dev/null 2>&1; then + echo "INSERT INTO recheck_requests (recheck_message_id, recheck_requested_by, recheck_series, recheck_patch, patchwork_instance, patchwork_project, recheck_sync) values (\"$recheck_msgid\", \"$recheck_requested_by\", \"$recheck_series\", $recheck_patch, \"$recheck_instance\", \"$recheck_project\", 0);" | series_db_execute + fi +} + +function get_recheck_request() { + local recheck_instance="$1" + local recheck_project="$2" + local recheck_msgid="$3" + local recheck_requested_by="$4" + local recheck_series="$5" + local recheck_state="$6" + + echo "select * from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\" and recheck_message_id=\"$recheck_msgid\" and recheck_sync=$recheck_state;" | series_db_execute +} + +function set_recheck_request_state() { + local recheck_instance="$1" + local recheck_project="$2" + local recheck_msgid="$3" + local recheck_requested_by="$4" + local recheck_series="$5" + local recheck_state="$6" + + echo "UPDATE recheck_requests set recheck_sync=$recheck_state where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\";" | series_db_execute +} -- 2.41.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments 2023-11-07 20:31 ` [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments Aaron Conole @ 2023-11-09 20:45 ` Dumitru Ceara 2023-11-10 14:05 ` Aaron Conole 2023-11-17 16:35 ` Michael Santana 1 sibling, 1 reply; 13+ messages in thread From: Dumitru Ceara @ 2023-11-09 20:45 UTC (permalink / raw) To: Aaron Conole, ci Cc: Michael Santana, David Marchand, Thomas Monjalon, Patrick Robb On 11/7/23 21:31, Aaron Conole wrote: > Add a recheck parsing tool that will allow for labs to build a > recheck workflow based on specific recheck labels and projects, > with an associated state machine and querying interface. > > The output of the recheck parsing tool is json and can be fed to > jq or other json parsing utilities for better field support. > > Signed-off-by: Aaron Conole <aconole@redhat.com> > --- Awesome, OVN really needs this kind of recheck capability in patchwork. One comment inline. > pw_mon | 58 ++++++++++++++++++++++++++- > recheck_tool | 100 +++++++++++++++++++++++++++++++++++++++++++++++ > series_db_lib.sh | 64 +++++++++++++++++++++++++++++- > 3 files changed, 220 insertions(+), 2 deletions(-) > create mode 100755 recheck_tool > > diff --git a/pw_mon b/pw_mon > index da4b9a9..29a9cb4 100755 > --- a/pw_mon > +++ b/pw_mon > @@ -1,6 +1,6 @@ > #!/bin/sh > # SPDX-Identifier: gpl-2.0-or-later > -# Copyright (C) 2018, Red Hat, Inc. > +# Copyright (C) 2018-2023 Red Hat, Inc. > # > # Monitors a project on a patchwork instance for new series submissions > # Records the submissions in the series database (and emits them on the > @@ -44,6 +44,7 @@ if [ "$1" != "" ]; then > fi > fi > > +recheck_filter="" > > while [ "$1" != "" ]; do > if echo "$1" | grep -q -s -E ^--pw-project= ; then > @@ -67,6 +68,10 @@ while [ "$1" != "" ]; do > echo " --add-filter-recheck=filter Adds a filter to flag that a recheck needs to be done" > echo "" > exit 0 > + elif echo "$1" | grep -q -s -E ^--add-filter-recheck=; then > + filter_str=$(echo "$1" | sed s/--add-filter-recheck=//) > + recheck_filter="$filter_str $recheck_filter" > + shift > else > echo "Unknown option: '$1'" > echo "Rerun with --help for details" > @@ -191,7 +196,58 @@ function check_superseded_series() { > done > } > > +function run_recheck() { > + local recheck_list=$(echo "$7" | sed -e 's/^Recheck-request: // ' -e 's/,/ /g') > + > + for filter in $recheck_filter; do > + for check in $recheck_list; do > + if [ "$filter" == "$check" ]; then > + insert_recheck_request_if_needed "$1" "$3" "$8" "$check" "$2" "$9" > + fi > + done > + done > +} > + > +function check_patch_for_retest_request() { > + local patch_url="$1" > + > + local patch_json=$(curl -s "$userpw" "$patch_url") > + local patch_comments_url=$(echo "$patch_json" | jq -rc '.comments') > + local patch_id=$(echo "$patch_json" | jq -rc '.id') > + if [ "Xnull" != "X$patch_comments_url" ]; then > + local comments_json=$(curl -s "$userpw" "$patch_comments_url") > + > + local seq_end=$(echo "$comments_json" | jq -rc 'length') > + if [ "$seq_end" -a $seq_end -gt 0 ]; then > + seq_end=$((seq_end-1)) > + for comment_id in $(seq 0 $seq_end); do > + local recheck_requested=$(echo "$comments_json" | jq -rc ".[$comment_id].content" | grep "^Recheck-request: ") This is "user facing", does the expected format of the comment need to be documented somewhere, e.g., in the README.rst file? On that note, can we add a reference to some of the documentation in the email the bot generates as reply to the patch in the series? Thanks, Dumitru > + if [ "X$recheck_requested" != "X" ]; then > + local msgid=$(echo "$comments_json" | jq -rc ".[$comment_id].msgid") > + run_recheck "$pw_instance" "$series_id" "$project" "$url" "$repo" "$branchname" "$recheck_requested" "$msgid" "$patch_id" > + fi > + done > + fi > + fi > +} > + > +function check_series_needs_retest() { > + local pw_instance="$1" > + > + series_get_active_branches "$pw_instance" | while IFS=\| read -r series_id project url repo branchname; do > + local patch_comments_url=$(curl -s "$userpw" "$url" | jq -rc '.patches[] | .url') > + > + for patch in $patch_comments_url; do > + check_patch_for_retest_request $patch > + done > + done > +} > + > check_undownloaded_series "$pw_instance" "$pw_project" > check_completed_series "$pw_instance" "$pw_project" > check_new_series "$pw_instance" "$pw_project" > check_superseded_series "$pw_instance" > + > +# check for retest requests after a series is still passing all the > +# checks above > +check_series_needs_retest "$pw_instance" > diff --git a/recheck_tool b/recheck_tool > new file mode 100755 > index 0000000..98031a9 > --- /dev/null > +++ b/recheck_tool > @@ -0,0 +1,100 @@ > +#!/bin/sh > +# SPDX-Identifier: gpl-2.0-or-later > +# Copyright (C) 2023 Red Hat, Inc. > +# > +# Licensed under the terms of the GNU General Public License as published > +# by the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. You may obtain a copy of the > +# license at > +# > +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html > +# > +# Unless required by applicable law or agreed to in writing, software > +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT > +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the > +# License for the specific language governing permissions and limitations > +# under the License. > + > +mode="select" > + > +while [ "$1" != "" ]; do > + if echo "$1" | grep -q -s -E ^--help ; then > + echo "recheck / retest state machine script" > + echo "" > + echo "$0:" > + echo " --pw-project=<proj>: Patchwork project." > + echo " --pw-instance=<inst>: Patchwork instance." > + echo " --filter=<str>: Job / request for recheck." > + echo " --state=<0..>: Resync state ID." > + echo " --msgid=<msgid>: Message ID to select." > + echo " --update: Set tool in update mode" > + echo " --new-state=<0..>: New state ID to set" > + echo " --series-id=<..>: Series ID" > + echo "" > + echo "Will spit out a parsable json for each db line when selecting" > + exit 0 > + elif echo "$1" | grep -q -s -E ^--pw-project= ; then > + pw_project=$(echo "$1" | sed s/^--pw-project=//) > + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then > + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) > + elif echo "$1" | grep -q -s -E ^--filter= ; then > + filter=$(echo "$1" | sed s/^--filter=//) > + elif echo "$1" | grep -q -s -E ^--state= ; then > + recheck_state=$(echo "$1" | sed s/^--state=//) > + elif echo "$1" | grep -q -s -E ^--msgid= ; then > + message_id=$(echo "$1" | sed s/^--msgid=//) > + elif echo "$1" | grep -q -s -E ^--update ; then > + mode="update" > + elif echo "$1" | grep -q -s -E ^--new-state= ; then > + new_recheck_state=$(echo "$1" | sed s/^--new-state=//) > + elif echo "$1" | grep -q -s -E ^--series-id= ; then > + series_id=$(echo "$1" | sed s/^--series-id=//) > + else > + echo "Unknown option: '$1'" > + echo "Rerun with --help for details" > + exit 1 > + fi > + shift > +done > + > +source $(dirname $0)/series_db_lib.sh > + > +if [ "$mode" == "select" ]; then > + echo -n "{\"rechecks\":[" > + printed="" > + for request in $(get_recheck_requests_by_project "$pw_instance" \ > + "$pw_project" \ > + "$recheck_state" \ > + "$filter"); do > + message_id=$(echo $request | cut -d\| -f1) > + series_id=$(echo $request | cut -d\| -f2) > + patch_id=$(echo $request | cut -d\| -f3) > + > + sha=$(get_sha_for_series_id_and_patch "$series_id" "$patch_id" \ > + "$pw_instance") > + echo -n "$printed{\"pw_instance\":\"$pw_instance\",\"series_id\":$series_id,\"patch_id\":$patch_id,\"sha\":\"$sha\",\"msg_id\":\"$message_id\",\"state\":\"$recheck_state\",\"requested\":\"$filter\"}" > + printed="," > + done > + echo "]}" > +elif [ "$mode" == "update" ]; then > + if [ "X$new_recheck_state" == "X" -o "X$series_id" == "X" ]; then > + echo "Need to set a series-id and a new recheck state when updating." > + exit 1 > + fi > + > + request=$(get_recheck_request "$pw_instance" "$pw_project" "$message_id" \ > + "$filter" "$series_id" "$recheck_state") > + if [ "X$request" == "X" ]; then > + echo "{\"result\":\"notfound\"}" > + exit 0 > + fi > + > + set_recheck_request_state "$pw_instance" "$pw_project" "$message_id" \ > + "$filter" "$series_id" "$new_recheck_state" > + > + echo "{\"result\":\"executed\",\"recheck\":{\"pw_instance\": \"$pw_instance\", \"series_id\":$series_id, \"msg_id\":\"$message_id\", \"state\":\"$new_recheck_state\", \"requested\": \"$filter\"}}" > +else > + echo "Unknown state: $mode" > + exit 1 > +fi > + > diff --git a/series_db_lib.sh b/series_db_lib.sh > index 6c2d98e..ca33c1f 100644 > --- a/series_db_lib.sh > +++ b/series_db_lib.sh > @@ -1,6 +1,6 @@ > #!/bin/sh > # SPDX-Identifier: gpl-2.0-or-later > -# Copyright (C) 2018,2019 Red Hat, Inc. > +# Copyright (C) 2018-2023 Red Hat, Inc. > # > # Licensed under the terms of the GNU General Public License as published > # by the Free Software Foundation; either version 2 of the License, or > @@ -114,6 +114,22 @@ EOF > run_db_command "INSERT INTO series_schema_version(id) values (7);" > fi > > + run_db_command "select * from series_schema_version;" | egrep '^8$' > /dev/null 2>&1 > + if [ $? -eq 1 ]; then > + sqlite3 ${HOME}/.series-db <<EOF > +CREATE TABLE recheck_requests ( > +recheck_id INTEGER, > +recheck_message_id STRING, > +recheck_requested_by STRING, > +recheck_series STRING, > +recheck_patch INTEGER, > +patchwork_instance STRING, > +patchwork_project STRING, > +recheck_sync INTEGER > +); > +EOF > + run_db_command "INSERT INTO series_schema_version(id) values (8);" > + fi > } > > function series_db_exists() { > @@ -390,3 +406,49 @@ function get_patch_id_by_series_id_and_sha() { > > echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute > } > + > +function get_recheck_requests_by_project() { > + local recheck_instance="$1" > + local recheck_project="$2" > + local recheck_state="$3" > + local recheck_requested_by="$4" > + > + series_db_exists > + > + echo "select recheck_message_id,recheck_series,recheck_patch from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_sync=$recheck_state and recheck_requested_by=\"$recheck_requested_by\";" | series_db_execute > +} > + > +function insert_recheck_request_if_needed() { > + local recheck_instance="$1" > + local recheck_project="$2" > + local recheck_msgid="$3" > + local recheck_requested_by="$4" > + local recheck_series="$5" > + local recheck_patch="$6" > + > + if ! echo "select * from recheck_requests where recheck_message_id=\"$recheck_msgid\";" | series_db_execute | grep $recheck_msgid >/dev/null 2>&1; then > + echo "INSERT INTO recheck_requests (recheck_message_id, recheck_requested_by, recheck_series, recheck_patch, patchwork_instance, patchwork_project, recheck_sync) values (\"$recheck_msgid\", \"$recheck_requested_by\", \"$recheck_series\", $recheck_patch, \"$recheck_instance\", \"$recheck_project\", 0);" | series_db_execute > + fi > +} > + > +function get_recheck_request() { > + local recheck_instance="$1" > + local recheck_project="$2" > + local recheck_msgid="$3" > + local recheck_requested_by="$4" > + local recheck_series="$5" > + local recheck_state="$6" > + > + echo "select * from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\" and recheck_message_id=\"$recheck_msgid\" and recheck_sync=$recheck_state;" | series_db_execute > +} > + > +function set_recheck_request_state() { > + local recheck_instance="$1" > + local recheck_project="$2" > + local recheck_msgid="$3" > + local recheck_requested_by="$4" > + local recheck_series="$5" > + local recheck_state="$6" > + > + echo "UPDATE recheck_requests set recheck_sync=$recheck_state where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\";" | series_db_execute > +} ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments 2023-11-09 20:45 ` Dumitru Ceara @ 2023-11-10 14:05 ` Aaron Conole 0 siblings, 0 replies; 13+ messages in thread From: Aaron Conole @ 2023-11-10 14:05 UTC (permalink / raw) To: Dumitru Ceara Cc: ci, Michael Santana, David Marchand, Thomas Monjalon, Patrick Robb Dumitru Ceara <dceara@redhat.com> writes: > On 11/7/23 21:31, Aaron Conole wrote: >> Add a recheck parsing tool that will allow for labs to build a >> recheck workflow based on specific recheck labels and projects, >> with an associated state machine and querying interface. >> >> The output of the recheck parsing tool is json and can be fed to >> jq or other json parsing utilities for better field support. >> >> Signed-off-by: Aaron Conole <aconole@redhat.com> >> --- > > Awesome, OVN really needs this kind of recheck capability in patchwork. > One comment inline. > >> pw_mon | 58 ++++++++++++++++++++++++++- >> recheck_tool | 100 +++++++++++++++++++++++++++++++++++++++++++++++ >> series_db_lib.sh | 64 +++++++++++++++++++++++++++++- >> 3 files changed, 220 insertions(+), 2 deletions(-) >> create mode 100755 recheck_tool >> >> diff --git a/pw_mon b/pw_mon >> index da4b9a9..29a9cb4 100755 >> --- a/pw_mon >> +++ b/pw_mon >> @@ -1,6 +1,6 @@ >> #!/bin/sh >> # SPDX-Identifier: gpl-2.0-or-later >> -# Copyright (C) 2018, Red Hat, Inc. >> +# Copyright (C) 2018-2023 Red Hat, Inc. >> # >> # Monitors a project on a patchwork instance for new series submissions >> # Records the submissions in the series database (and emits them on the >> @@ -44,6 +44,7 @@ if [ "$1" != "" ]; then >> fi >> fi >> >> +recheck_filter="" >> >> while [ "$1" != "" ]; do >> if echo "$1" | grep -q -s -E ^--pw-project= ; then >> @@ -67,6 +68,10 @@ while [ "$1" != "" ]; do >> echo " --add-filter-recheck=filter Adds a filter to flag that a recheck needs to be done" >> echo "" >> exit 0 >> + elif echo "$1" | grep -q -s -E ^--add-filter-recheck=; then >> + filter_str=$(echo "$1" | sed s/--add-filter-recheck=//) >> + recheck_filter="$filter_str $recheck_filter" >> + shift >> else >> echo "Unknown option: '$1'" >> echo "Rerun with --help for details" >> @@ -191,7 +196,58 @@ function check_superseded_series() { >> done >> } >> >> +function run_recheck() { >> + local recheck_list=$(echo "$7" | sed -e 's/^Recheck-request: // ' -e 's/,/ /g') >> + >> + for filter in $recheck_filter; do >> + for check in $recheck_list; do >> + if [ "$filter" == "$check" ]; then >> + insert_recheck_request_if_needed "$1" "$3" "$8" "$check" "$2" "$9" >> + fi >> + done >> + done >> +} >> + >> +function check_patch_for_retest_request() { >> + local patch_url="$1" >> + >> + local patch_json=$(curl -s "$userpw" "$patch_url") >> + local patch_comments_url=$(echo "$patch_json" | jq -rc '.comments') >> + local patch_id=$(echo "$patch_json" | jq -rc '.id') >> + if [ "Xnull" != "X$patch_comments_url" ]; then >> + local comments_json=$(curl -s "$userpw" "$patch_comments_url") >> + >> + local seq_end=$(echo "$comments_json" | jq -rc 'length') >> + if [ "$seq_end" -a $seq_end -gt 0 ]; then >> + seq_end=$((seq_end-1)) >> + for comment_id in $(seq 0 $seq_end); do >> + local recheck_requested=$(echo "$comments_json" | jq -rc ".[$comment_id].content" | grep "^Recheck-request: ") > > This is "user facing", does the expected format of the comment need to > be documented somewhere, e.g., in the README.rst file? We definitely **should** add this to some documentation. For now, it is just knowledge we roll around in our heads. OTOH, the recheck was discussed at: https://mails.dpdk.org/archives/ci/2021-May/001189.html So we did argue a bit about the formatting, etc. For OVN project (for example), we probably would want two different test names - one for the ovn-kubernetes workflow, and one for the build and test workflow. And that is something we can hash out and at least announce (with possibly some documentation in the OVN tree). > On that note, can we add a reference to some of the documentation in the > email the bot generates as reply to the patch in the series? That's a good idea. I need to spend some time to write the up a comprehensive documentation of the robot anyway. > Thanks, > Dumitru > >> + if [ "X$recheck_requested" != "X" ]; then >> + local msgid=$(echo "$comments_json" | jq -rc ".[$comment_id].msgid") >> + run_recheck "$pw_instance" "$series_id" "$project" "$url" "$repo" "$branchname" "$recheck_requested" "$msgid" "$patch_id" >> + fi >> + done >> + fi >> + fi >> +} >> + >> +function check_series_needs_retest() { >> + local pw_instance="$1" >> + >> + series_get_active_branches "$pw_instance" | while IFS=\| read -r series_id project url repo branchname; do >> + local patch_comments_url=$(curl -s "$userpw" "$url" | jq -rc '.patches[] | .url') >> + >> + for patch in $patch_comments_url; do >> + check_patch_for_retest_request $patch >> + done >> + done >> +} >> + >> check_undownloaded_series "$pw_instance" "$pw_project" >> check_completed_series "$pw_instance" "$pw_project" >> check_new_series "$pw_instance" "$pw_project" >> check_superseded_series "$pw_instance" >> + >> +# check for retest requests after a series is still passing all the >> +# checks above >> +check_series_needs_retest "$pw_instance" >> diff --git a/recheck_tool b/recheck_tool >> new file mode 100755 >> index 0000000..98031a9 >> --- /dev/null >> +++ b/recheck_tool >> @@ -0,0 +1,100 @@ >> +#!/bin/sh >> +# SPDX-Identifier: gpl-2.0-or-later >> +# Copyright (C) 2023 Red Hat, Inc. >> +# >> +# Licensed under the terms of the GNU General Public License as published >> +# by the Free Software Foundation; either version 2 of the License, or >> +# (at your option) any later version. You may obtain a copy of the >> +# license at >> +# >> +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html >> +# >> +# Unless required by applicable law or agreed to in writing, software >> +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT >> +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the >> +# License for the specific language governing permissions and limitations >> +# under the License. >> + >> +mode="select" >> + >> +while [ "$1" != "" ]; do >> + if echo "$1" | grep -q -s -E ^--help ; then >> + echo "recheck / retest state machine script" >> + echo "" >> + echo "$0:" >> + echo " --pw-project=<proj>: Patchwork project." >> + echo " --pw-instance=<inst>: Patchwork instance." >> + echo " --filter=<str>: Job / request for recheck." >> + echo " --state=<0..>: Resync state ID." >> + echo " --msgid=<msgid>: Message ID to select." >> + echo " --update: Set tool in update mode" >> + echo " --new-state=<0..>: New state ID to set" >> + echo " --series-id=<..>: Series ID" >> + echo "" >> + echo "Will spit out a parsable json for each db line when selecting" >> + exit 0 >> + elif echo "$1" | grep -q -s -E ^--pw-project= ; then >> + pw_project=$(echo "$1" | sed s/^--pw-project=//) >> + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then >> + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) >> + elif echo "$1" | grep -q -s -E ^--filter= ; then >> + filter=$(echo "$1" | sed s/^--filter=//) >> + elif echo "$1" | grep -q -s -E ^--state= ; then >> + recheck_state=$(echo "$1" | sed s/^--state=//) >> + elif echo "$1" | grep -q -s -E ^--msgid= ; then >> + message_id=$(echo "$1" | sed s/^--msgid=//) >> + elif echo "$1" | grep -q -s -E ^--update ; then >> + mode="update" >> + elif echo "$1" | grep -q -s -E ^--new-state= ; then >> + new_recheck_state=$(echo "$1" | sed s/^--new-state=//) >> + elif echo "$1" | grep -q -s -E ^--series-id= ; then >> + series_id=$(echo "$1" | sed s/^--series-id=//) >> + else >> + echo "Unknown option: '$1'" >> + echo "Rerun with --help for details" >> + exit 1 >> + fi >> + shift >> +done >> + >> +source $(dirname $0)/series_db_lib.sh >> + >> +if [ "$mode" == "select" ]; then >> + echo -n "{\"rechecks\":[" >> + printed="" >> + for request in $(get_recheck_requests_by_project "$pw_instance" \ >> + "$pw_project" \ >> + "$recheck_state" \ >> + "$filter"); do >> + message_id=$(echo $request | cut -d\| -f1) >> + series_id=$(echo $request | cut -d\| -f2) >> + patch_id=$(echo $request | cut -d\| -f3) >> + >> + sha=$(get_sha_for_series_id_and_patch "$series_id" "$patch_id" \ >> + "$pw_instance") >> + echo -n "$printed{\"pw_instance\":\"$pw_instance\",\"series_id\":$series_id,\"patch_id\":$patch_id,\"sha\":\"$sha\",\"msg_id\":\"$message_id\",\"state\":\"$recheck_state\",\"requested\":\"$filter\"}" >> + printed="," >> + done >> + echo "]}" >> +elif [ "$mode" == "update" ]; then >> + if [ "X$new_recheck_state" == "X" -o "X$series_id" == "X" ]; then >> + echo "Need to set a series-id and a new recheck state when updating." >> + exit 1 >> + fi >> + >> + request=$(get_recheck_request "$pw_instance" "$pw_project" "$message_id" \ >> + "$filter" "$series_id" "$recheck_state") >> + if [ "X$request" == "X" ]; then >> + echo "{\"result\":\"notfound\"}" >> + exit 0 >> + fi >> + >> + set_recheck_request_state "$pw_instance" "$pw_project" "$message_id" \ >> + "$filter" "$series_id" "$new_recheck_state" >> + >> + echo "{\"result\":\"executed\",\"recheck\":{\"pw_instance\": \"$pw_instance\", \"series_id\":$series_id, \"msg_id\":\"$message_id\", \"state\":\"$new_recheck_state\", \"requested\": \"$filter\"}}" >> +else >> + echo "Unknown state: $mode" >> + exit 1 >> +fi >> + >> diff --git a/series_db_lib.sh b/series_db_lib.sh >> index 6c2d98e..ca33c1f 100644 >> --- a/series_db_lib.sh >> +++ b/series_db_lib.sh >> @@ -1,6 +1,6 @@ >> #!/bin/sh >> # SPDX-Identifier: gpl-2.0-or-later >> -# Copyright (C) 2018,2019 Red Hat, Inc. >> +# Copyright (C) 2018-2023 Red Hat, Inc. >> # >> # Licensed under the terms of the GNU General Public License as published >> # by the Free Software Foundation; either version 2 of the License, or >> @@ -114,6 +114,22 @@ EOF >> run_db_command "INSERT INTO series_schema_version(id) values (7);" >> fi >> >> + run_db_command "select * from series_schema_version;" | egrep '^8$' > /dev/null 2>&1 >> + if [ $? -eq 1 ]; then >> + sqlite3 ${HOME}/.series-db <<EOF >> +CREATE TABLE recheck_requests ( >> +recheck_id INTEGER, >> +recheck_message_id STRING, >> +recheck_requested_by STRING, >> +recheck_series STRING, >> +recheck_patch INTEGER, >> +patchwork_instance STRING, >> +patchwork_project STRING, >> +recheck_sync INTEGER >> +); >> +EOF >> + run_db_command "INSERT INTO series_schema_version(id) values (8);" >> + fi >> } >> >> function series_db_exists() { >> @@ -390,3 +406,49 @@ function get_patch_id_by_series_id_and_sha() { >> >> echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute >> } >> + >> +function get_recheck_requests_by_project() { >> + local recheck_instance="$1" >> + local recheck_project="$2" >> + local recheck_state="$3" >> + local recheck_requested_by="$4" >> + >> + series_db_exists >> + >> + echo "select recheck_message_id,recheck_series,recheck_patch from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_sync=$recheck_state and recheck_requested_by=\"$recheck_requested_by\";" | series_db_execute >> +} >> + >> +function insert_recheck_request_if_needed() { >> + local recheck_instance="$1" >> + local recheck_project="$2" >> + local recheck_msgid="$3" >> + local recheck_requested_by="$4" >> + local recheck_series="$5" >> + local recheck_patch="$6" >> + >> + if ! echo "select * from recheck_requests where recheck_message_id=\"$recheck_msgid\";" | series_db_execute | grep $recheck_msgid >/dev/null 2>&1; then >> + echo "INSERT INTO recheck_requests (recheck_message_id, recheck_requested_by, recheck_series, recheck_patch, patchwork_instance, patchwork_project, recheck_sync) values (\"$recheck_msgid\", \"$recheck_requested_by\", \"$recheck_series\", $recheck_patch, \"$recheck_instance\", \"$recheck_project\", 0);" | series_db_execute >> + fi >> +} >> + >> +function get_recheck_request() { >> + local recheck_instance="$1" >> + local recheck_project="$2" >> + local recheck_msgid="$3" >> + local recheck_requested_by="$4" >> + local recheck_series="$5" >> + local recheck_state="$6" >> + >> + echo "select * from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\" and recheck_message_id=\"$recheck_msgid\" and recheck_sync=$recheck_state;" | series_db_execute >> +} >> + >> +function set_recheck_request_state() { >> + local recheck_instance="$1" >> + local recheck_project="$2" >> + local recheck_msgid="$3" >> + local recheck_requested_by="$4" >> + local recheck_series="$5" >> + local recheck_state="$6" >> + >> + echo "UPDATE recheck_requests set recheck_sync=$recheck_state where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\";" | series_db_execute >> +} ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments 2023-11-07 20:31 ` [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments Aaron Conole 2023-11-09 20:45 ` Dumitru Ceara @ 2023-11-17 16:35 ` Michael Santana 2023-11-17 19:28 ` Aaron Conole 1 sibling, 1 reply; 13+ messages in thread From: Michael Santana @ 2023-11-17 16:35 UTC (permalink / raw) To: Aaron Conole Cc: ci, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara On Tue, Nov 7, 2023 at 3:32 PM Aaron Conole <aconole@redhat.com> wrote: > > Add a recheck parsing tool that will allow for labs to build a > recheck workflow based on specific recheck labels and projects, > with an associated state machine and querying interface. > > The output of the recheck parsing tool is json and can be fed to > jq or other json parsing utilities for better field support. > > Signed-off-by: Aaron Conole <aconole@redhat.com> Acked-by: Michael Santana <msantana@redhat.com> > --- > pw_mon | 58 ++++++++++++++++++++++++++- > recheck_tool | 100 +++++++++++++++++++++++++++++++++++++++++++++++ > series_db_lib.sh | 64 +++++++++++++++++++++++++++++- > 3 files changed, 220 insertions(+), 2 deletions(-) > create mode 100755 recheck_tool > > diff --git a/pw_mon b/pw_mon > index da4b9a9..29a9cb4 100755 > --- a/pw_mon > +++ b/pw_mon > @@ -1,6 +1,6 @@ > #!/bin/sh > # SPDX-Identifier: gpl-2.0-or-later > -# Copyright (C) 2018, Red Hat, Inc. > +# Copyright (C) 2018-2023 Red Hat, Inc. > # > # Monitors a project on a patchwork instance for new series submissions > # Records the submissions in the series database (and emits them on the > @@ -44,6 +44,7 @@ if [ "$1" != "" ]; then > fi > fi > > +recheck_filter="" > > while [ "$1" != "" ]; do > if echo "$1" | grep -q -s -E ^--pw-project= ; then > @@ -67,6 +68,10 @@ while [ "$1" != "" ]; do > echo " --add-filter-recheck=filter Adds a filter to flag that a recheck needs to be done" > echo "" > exit 0 > + elif echo "$1" | grep -q -s -E ^--add-filter-recheck=; then > + filter_str=$(echo "$1" | sed s/--add-filter-recheck=//) > + recheck_filter="$filter_str $recheck_filter" > + shift > else > echo "Unknown option: '$1'" > echo "Rerun with --help for details" > @@ -191,7 +196,58 @@ function check_superseded_series() { > done > } > > +function run_recheck() { > + local recheck_list=$(echo "$7" | sed -e 's/^Recheck-request: // ' -e 's/,/ /g') > + > + for filter in $recheck_filter; do > + for check in $recheck_list; do > + if [ "$filter" == "$check" ]; then > + insert_recheck_request_if_needed "$1" "$3" "$8" "$check" "$2" "$9" > + fi > + done > + done > +} > + > +function check_patch_for_retest_request() { > + local patch_url="$1" > + > + local patch_json=$(curl -s "$userpw" "$patch_url") > + local patch_comments_url=$(echo "$patch_json" | jq -rc '.comments') > + local patch_id=$(echo "$patch_json" | jq -rc '.id') > + if [ "Xnull" != "X$patch_comments_url" ]; then > + local comments_json=$(curl -s "$userpw" "$patch_comments_url") > + > + local seq_end=$(echo "$comments_json" | jq -rc 'length') > + if [ "$seq_end" -a $seq_end -gt 0 ]; then > + seq_end=$((seq_end-1)) > + for comment_id in $(seq 0 $seq_end); do > + local recheck_requested=$(echo "$comments_json" | jq -rc ".[$comment_id].content" | grep "^Recheck-request: ") > + if [ "X$recheck_requested" != "X" ]; then > + local msgid=$(echo "$comments_json" | jq -rc ".[$comment_id].msgid") > + run_recheck "$pw_instance" "$series_id" "$project" "$url" "$repo" "$branchname" "$recheck_requested" "$msgid" "$patch_id" > + fi > + done > + fi > + fi > +} > + > +function check_series_needs_retest() { > + local pw_instance="$1" > + > + series_get_active_branches "$pw_instance" | while IFS=\| read -r series_id project url repo branchname; do > + local patch_comments_url=$(curl -s "$userpw" "$url" | jq -rc '.patches[] | .url') > + > + for patch in $patch_comments_url; do > + check_patch_for_retest_request $patch > + done > + done > +} > + > check_undownloaded_series "$pw_instance" "$pw_project" > check_completed_series "$pw_instance" "$pw_project" > check_new_series "$pw_instance" "$pw_project" > check_superseded_series "$pw_instance" > + > +# check for retest requests after a series is still passing all the > +# checks above > +check_series_needs_retest "$pw_instance" > diff --git a/recheck_tool b/recheck_tool > new file mode 100755 > index 0000000..98031a9 > --- /dev/null > +++ b/recheck_tool > @@ -0,0 +1,100 @@ > +#!/bin/sh > +# SPDX-Identifier: gpl-2.0-or-later > +# Copyright (C) 2023 Red Hat, Inc. > +# > +# Licensed under the terms of the GNU General Public License as published > +# by the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. You may obtain a copy of the > +# license at > +# > +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html > +# > +# Unless required by applicable law or agreed to in writing, software > +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT > +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the > +# License for the specific language governing permissions and limitations > +# under the License. > + > +mode="select" > + > +while [ "$1" != "" ]; do > + if echo "$1" | grep -q -s -E ^--help ; then > + echo "recheck / retest state machine script" > + echo "" > + echo "$0:" > + echo " --pw-project=<proj>: Patchwork project." > + echo " --pw-instance=<inst>: Patchwork instance." > + echo " --filter=<str>: Job / request for recheck." > + echo " --state=<0..>: Resync state ID." > + echo " --msgid=<msgid>: Message ID to select." > + echo " --update: Set tool in update mode" > + echo " --new-state=<0..>: New state ID to set" > + echo " --series-id=<..>: Series ID" > + echo "" > + echo "Will spit out a parsable json for each db line when selecting" LGTM. But to Dumitru's point, maybe we should add documentation this this in a follow up patch > + exit 0 > + elif echo "$1" | grep -q -s -E ^--pw-project= ; then > + pw_project=$(echo "$1" | sed s/^--pw-project=//) > + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then > + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) > + elif echo "$1" | grep -q -s -E ^--filter= ; then > + filter=$(echo "$1" | sed s/^--filter=//) > + elif echo "$1" | grep -q -s -E ^--state= ; then > + recheck_state=$(echo "$1" | sed s/^--state=//) > + elif echo "$1" | grep -q -s -E ^--msgid= ; then > + message_id=$(echo "$1" | sed s/^--msgid=//) > + elif echo "$1" | grep -q -s -E ^--update ; then > + mode="update" > + elif echo "$1" | grep -q -s -E ^--new-state= ; then > + new_recheck_state=$(echo "$1" | sed s/^--new-state=//) > + elif echo "$1" | grep -q -s -E ^--series-id= ; then > + series_id=$(echo "$1" | sed s/^--series-id=//) > + else > + echo "Unknown option: '$1'" > + echo "Rerun with --help for details" > + exit 1 > + fi > + shift > +done > + > +source $(dirname $0)/series_db_lib.sh > + > +if [ "$mode" == "select" ]; then > + echo -n "{\"rechecks\":[" > + printed="" > + for request in $(get_recheck_requests_by_project "$pw_instance" \ > + "$pw_project" \ > + "$recheck_state" \ > + "$filter"); do > + message_id=$(echo $request | cut -d\| -f1) > + series_id=$(echo $request | cut -d\| -f2) > + patch_id=$(echo $request | cut -d\| -f3) > + > + sha=$(get_sha_for_series_id_and_patch "$series_id" "$patch_id" \ > + "$pw_instance") > + echo -n "$printed{\"pw_instance\":\"$pw_instance\",\"series_id\":$series_id,\"patch_id\":$patch_id,\"sha\":\"$sha\",\"msg_id\":\"$message_id\",\"state\":\"$recheck_state\",\"requested\":\"$filter\"}" okay, smart use of the -n for the echo command. I see you are also taking care of the coma which is good! > + printed="," > + done > + echo "]}" > +elif [ "$mode" == "update" ]; then > + if [ "X$new_recheck_state" == "X" -o "X$series_id" == "X" ]; then > + echo "Need to set a series-id and a new recheck state when updating." > + exit 1 > + fi > + > + request=$(get_recheck_request "$pw_instance" "$pw_project" "$message_id" \ > + "$filter" "$series_id" "$recheck_state") > + if [ "X$request" == "X" ]; then > + echo "{\"result\":\"notfound\"}" > + exit 0 > + fi > + > + set_recheck_request_state "$pw_instance" "$pw_project" "$message_id" \ > + "$filter" "$series_id" "$new_recheck_state" > + > + echo "{\"result\":\"executed\",\"recheck\":{\"pw_instance\": \"$pw_instance\", \"series_id\":$series_id, \"msg_id\":\"$message_id\", \"state\":\"$new_recheck_state\", \"requested\": \"$filter\"}}" okay > +else > + echo "Unknown state: $mode" > + exit 1 > +fi > + > diff --git a/series_db_lib.sh b/series_db_lib.sh > index 6c2d98e..ca33c1f 100644 > --- a/series_db_lib.sh > +++ b/series_db_lib.sh > @@ -1,6 +1,6 @@ > #!/bin/sh > # SPDX-Identifier: gpl-2.0-or-later > -# Copyright (C) 2018,2019 Red Hat, Inc. > +# Copyright (C) 2018-2023 Red Hat, Inc. > # > # Licensed under the terms of the GNU General Public License as published > # by the Free Software Foundation; either version 2 of the License, or > @@ -114,6 +114,22 @@ EOF > run_db_command "INSERT INTO series_schema_version(id) values (7);" > fi > > + run_db_command "select * from series_schema_version;" | egrep '^8$' > /dev/null 2>&1 > + if [ $? -eq 1 ]; then > + sqlite3 ${HOME}/.series-db <<EOF > +CREATE TABLE recheck_requests ( > +recheck_id INTEGER, > +recheck_message_id STRING, > +recheck_requested_by STRING, > +recheck_series STRING, > +recheck_patch INTEGER, > +patchwork_instance STRING, > +patchwork_project STRING, > +recheck_sync INTEGER > +); > +EOF > + run_db_command "INSERT INTO series_schema_version(id) values (8);" > + fi > } > > function series_db_exists() { > @@ -390,3 +406,49 @@ function get_patch_id_by_series_id_and_sha() { > > echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute > } > + > +function get_recheck_requests_by_project() { > + local recheck_instance="$1" > + local recheck_project="$2" > + local recheck_state="$3" > + local recheck_requested_by="$4" > + > + series_db_exists > + > + echo "select recheck_message_id,recheck_series,recheck_patch from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_sync=$recheck_state and recheck_requested_by=\"$recheck_requested_by\";" | series_db_execute > +} > + > +function insert_recheck_request_if_needed() { > + local recheck_instance="$1" > + local recheck_project="$2" > + local recheck_msgid="$3" > + local recheck_requested_by="$4" > + local recheck_series="$5" > + local recheck_patch="$6" > + > + if ! echo "select * from recheck_requests where recheck_message_id=\"$recheck_msgid\";" | series_db_execute | grep $recheck_msgid >/dev/null 2>&1; then > + echo "INSERT INTO recheck_requests (recheck_message_id, recheck_requested_by, recheck_series, recheck_patch, patchwork_instance, patchwork_project, recheck_sync) values (\"$recheck_msgid\", \"$recheck_requested_by\", \"$recheck_series\", $recheck_patch, \"$recheck_instance\", \"$recheck_project\", 0);" | series_db_execute > + fi > +} > + > +function get_recheck_request() { > + local recheck_instance="$1" > + local recheck_project="$2" > + local recheck_msgid="$3" > + local recheck_requested_by="$4" > + local recheck_series="$5" > + local recheck_state="$6" > + > + echo "select * from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\" and recheck_message_id=\"$recheck_msgid\" and recheck_sync=$recheck_state;" | series_db_execute > +} > + > +function set_recheck_request_state() { > + local recheck_instance="$1" > + local recheck_project="$2" > + local recheck_msgid="$3" > + local recheck_requested_by="$4" > + local recheck_series="$5" > + local recheck_state="$6" > + > + echo "UPDATE recheck_requests set recheck_sync=$recheck_state where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\";" | series_db_execute > +} > -- > 2.41.0 > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments 2023-11-17 16:35 ` Michael Santana @ 2023-11-17 19:28 ` Aaron Conole 0 siblings, 0 replies; 13+ messages in thread From: Aaron Conole @ 2023-11-17 19:28 UTC (permalink / raw) To: Michael Santana Cc: ci, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara Michael Santana <msantana@redhat.com> writes: > On Tue, Nov 7, 2023 at 3:32 PM Aaron Conole <aconole@redhat.com> wrote: >> >> Add a recheck parsing tool that will allow for labs to build a >> recheck workflow based on specific recheck labels and projects, >> with an associated state machine and querying interface. >> >> The output of the recheck parsing tool is json and can be fed to >> jq or other json parsing utilities for better field support. >> >> Signed-off-by: Aaron Conole <aconole@redhat.com> > Acked-by: Michael Santana <msantana@redhat.com> Thanks >> --- >> pw_mon | 58 ++++++++++++++++++++++++++- >> recheck_tool | 100 +++++++++++++++++++++++++++++++++++++++++++++++ >> series_db_lib.sh | 64 +++++++++++++++++++++++++++++- >> 3 files changed, 220 insertions(+), 2 deletions(-) >> create mode 100755 recheck_tool >> >> diff --git a/pw_mon b/pw_mon >> index da4b9a9..29a9cb4 100755 >> --- a/pw_mon >> +++ b/pw_mon >> @@ -1,6 +1,6 @@ >> #!/bin/sh >> # SPDX-Identifier: gpl-2.0-or-later >> -# Copyright (C) 2018, Red Hat, Inc. >> +# Copyright (C) 2018-2023 Red Hat, Inc. >> # >> # Monitors a project on a patchwork instance for new series submissions >> # Records the submissions in the series database (and emits them on the >> @@ -44,6 +44,7 @@ if [ "$1" != "" ]; then >> fi >> fi >> >> +recheck_filter="" >> >> while [ "$1" != "" ]; do >> if echo "$1" | grep -q -s -E ^--pw-project= ; then >> @@ -67,6 +68,10 @@ while [ "$1" != "" ]; do >> echo " --add-filter-recheck=filter Adds a filter to flag that a recheck needs to be done" >> echo "" >> exit 0 >> + elif echo "$1" | grep -q -s -E ^--add-filter-recheck=; then >> + filter_str=$(echo "$1" | sed s/--add-filter-recheck=//) >> + recheck_filter="$filter_str $recheck_filter" >> + shift >> else >> echo "Unknown option: '$1'" >> echo "Rerun with --help for details" >> @@ -191,7 +196,58 @@ function check_superseded_series() { >> done >> } >> >> +function run_recheck() { >> + local recheck_list=$(echo "$7" | sed -e 's/^Recheck-request: // ' -e 's/,/ /g') >> + >> + for filter in $recheck_filter; do >> + for check in $recheck_list; do >> + if [ "$filter" == "$check" ]; then >> + insert_recheck_request_if_needed "$1" "$3" "$8" "$check" "$2" "$9" >> + fi >> + done >> + done >> +} >> + >> +function check_patch_for_retest_request() { >> + local patch_url="$1" >> + >> + local patch_json=$(curl -s "$userpw" "$patch_url") >> + local patch_comments_url=$(echo "$patch_json" | jq -rc '.comments') >> + local patch_id=$(echo "$patch_json" | jq -rc '.id') >> + if [ "Xnull" != "X$patch_comments_url" ]; then >> + local comments_json=$(curl -s "$userpw" "$patch_comments_url") >> + >> + local seq_end=$(echo "$comments_json" | jq -rc 'length') >> + if [ "$seq_end" -a $seq_end -gt 0 ]; then >> + seq_end=$((seq_end-1)) >> + for comment_id in $(seq 0 $seq_end); do >> + local recheck_requested=$(echo "$comments_json" | jq -rc ".[$comment_id].content" | grep "^Recheck-request: ") >> + if [ "X$recheck_requested" != "X" ]; then >> + local msgid=$(echo "$comments_json" | jq -rc ".[$comment_id].msgid") >> + run_recheck "$pw_instance" "$series_id" "$project" "$url" "$repo" "$branchname" "$recheck_requested" "$msgid" "$patch_id" >> + fi >> + done >> + fi >> + fi >> +} >> + >> +function check_series_needs_retest() { >> + local pw_instance="$1" >> + >> + series_get_active_branches "$pw_instance" | while IFS=\| read -r series_id project url repo branchname; do >> + local patch_comments_url=$(curl -s "$userpw" "$url" | jq -rc '.patches[] | .url') >> + >> + for patch in $patch_comments_url; do >> + check_patch_for_retest_request $patch >> + done >> + done >> +} >> + >> check_undownloaded_series "$pw_instance" "$pw_project" >> check_completed_series "$pw_instance" "$pw_project" >> check_new_series "$pw_instance" "$pw_project" >> check_superseded_series "$pw_instance" >> + >> +# check for retest requests after a series is still passing all the >> +# checks above >> +check_series_needs_retest "$pw_instance" >> diff --git a/recheck_tool b/recheck_tool >> new file mode 100755 >> index 0000000..98031a9 >> --- /dev/null >> +++ b/recheck_tool >> @@ -0,0 +1,100 @@ >> +#!/bin/sh >> +# SPDX-Identifier: gpl-2.0-or-later >> +# Copyright (C) 2023 Red Hat, Inc. >> +# >> +# Licensed under the terms of the GNU General Public License as published >> +# by the Free Software Foundation; either version 2 of the License, or >> +# (at your option) any later version. You may obtain a copy of the >> +# license at >> +# >> +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html >> +# >> +# Unless required by applicable law or agreed to in writing, software >> +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT >> +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the >> +# License for the specific language governing permissions and limitations >> +# under the License. >> + >> +mode="select" >> + >> +while [ "$1" != "" ]; do >> + if echo "$1" | grep -q -s -E ^--help ; then >> + echo "recheck / retest state machine script" >> + echo "" >> + echo "$0:" >> + echo " --pw-project=<proj>: Patchwork project." >> + echo " --pw-instance=<inst>: Patchwork instance." >> + echo " --filter=<str>: Job / request for recheck." >> + echo " --state=<0..>: Resync state ID." >> + echo " --msgid=<msgid>: Message ID to select." >> + echo " --update: Set tool in update mode" >> + echo " --new-state=<0..>: New state ID to set" >> + echo " --series-id=<..>: Series ID" >> + echo "" >> + echo "Will spit out a parsable json for each db line when selecting" > LGTM. But to Dumitru's point, maybe we should add documentation this > this in a follow up patch >> + exit 0 >> + elif echo "$1" | grep -q -s -E ^--pw-project= ; then >> + pw_project=$(echo "$1" | sed s/^--pw-project=//) >> + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then >> + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) >> + elif echo "$1" | grep -q -s -E ^--filter= ; then >> + filter=$(echo "$1" | sed s/^--filter=//) >> + elif echo "$1" | grep -q -s -E ^--state= ; then >> + recheck_state=$(echo "$1" | sed s/^--state=//) >> + elif echo "$1" | grep -q -s -E ^--msgid= ; then >> + message_id=$(echo "$1" | sed s/^--msgid=//) >> + elif echo "$1" | grep -q -s -E ^--update ; then >> + mode="update" >> + elif echo "$1" | grep -q -s -E ^--new-state= ; then >> + new_recheck_state=$(echo "$1" | sed s/^--new-state=//) >> + elif echo "$1" | grep -q -s -E ^--series-id= ; then >> + series_id=$(echo "$1" | sed s/^--series-id=//) >> + else >> + echo "Unknown option: '$1'" >> + echo "Rerun with --help for details" >> + exit 1 >> + fi >> + shift >> +done >> + >> +source $(dirname $0)/series_db_lib.sh >> + >> +if [ "$mode" == "select" ]; then >> + echo -n "{\"rechecks\":[" >> + printed="" >> + for request in $(get_recheck_requests_by_project "$pw_instance" \ >> + "$pw_project" \ >> + "$recheck_state" \ >> + "$filter"); do >> + message_id=$(echo $request | cut -d\| -f1) >> + series_id=$(echo $request | cut -d\| -f2) >> + patch_id=$(echo $request | cut -d\| -f3) >> + >> + sha=$(get_sha_for_series_id_and_patch "$series_id" "$patch_id" \ >> + "$pw_instance") >> + echo -n >> "$printed{\"pw_instance\":\"$pw_instance\",\"series_id\":$series_id,\"patch_id\":$patch_id,\"sha\":\"$sha\",\"msg_id\":\"$message_id\",\"state\":\"$recheck_state\",\"requested\":\"$filter\"}" > okay, smart use of the -n for the echo command. I see you are also > taking care of the coma which is good! >> + printed="," >> + done >> + echo "]}" >> +elif [ "$mode" == "update" ]; then >> + if [ "X$new_recheck_state" == "X" -o "X$series_id" == "X" ]; then >> + echo "Need to set a series-id and a new recheck state when updating." >> + exit 1 >> + fi >> + >> + request=$(get_recheck_request "$pw_instance" "$pw_project" "$message_id" \ >> + "$filter" "$series_id" "$recheck_state") >> + if [ "X$request" == "X" ]; then >> + echo "{\"result\":\"notfound\"}" >> + exit 0 >> + fi >> + >> + set_recheck_request_state "$pw_instance" "$pw_project" "$message_id" \ >> + "$filter" "$series_id" "$new_recheck_state" >> + >> + echo "{\"result\":\"executed\",\"recheck\":{\"pw_instance\": >> \"$pw_instance\", \"series_id\":$series_id, >> \"msg_id\":\"$message_id\", \"state\":\"$new_recheck_state\", >> \"requested\": \"$filter\"}}" > okay >> +else >> + echo "Unknown state: $mode" >> + exit 1 >> +fi >> + >> diff --git a/series_db_lib.sh b/series_db_lib.sh >> index 6c2d98e..ca33c1f 100644 >> --- a/series_db_lib.sh >> +++ b/series_db_lib.sh >> @@ -1,6 +1,6 @@ >> #!/bin/sh >> # SPDX-Identifier: gpl-2.0-or-later >> -# Copyright (C) 2018,2019 Red Hat, Inc. >> +# Copyright (C) 2018-2023 Red Hat, Inc. >> # >> # Licensed under the terms of the GNU General Public License as published >> # by the Free Software Foundation; either version 2 of the License, or >> @@ -114,6 +114,22 @@ EOF >> run_db_command "INSERT INTO series_schema_version(id) values (7);" >> fi >> >> + run_db_command "select * from series_schema_version;" | egrep '^8$' > /dev/null 2>&1 >> + if [ $? -eq 1 ]; then >> + sqlite3 ${HOME}/.series-db <<EOF >> +CREATE TABLE recheck_requests ( >> +recheck_id INTEGER, >> +recheck_message_id STRING, >> +recheck_requested_by STRING, >> +recheck_series STRING, >> +recheck_patch INTEGER, >> +patchwork_instance STRING, >> +patchwork_project STRING, >> +recheck_sync INTEGER >> +); >> +EOF >> + run_db_command "INSERT INTO series_schema_version(id) values (8);" >> + fi >> } >> >> function series_db_exists() { >> @@ -390,3 +406,49 @@ function get_patch_id_by_series_id_and_sha() { >> >> echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute >> } >> + >> +function get_recheck_requests_by_project() { >> + local recheck_instance="$1" >> + local recheck_project="$2" >> + local recheck_state="$3" >> + local recheck_requested_by="$4" >> + >> + series_db_exists >> + >> + echo "select recheck_message_id,recheck_series,recheck_patch from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_sync=$recheck_state and recheck_requested_by=\"$recheck_requested_by\";" | series_db_execute >> +} >> + >> +function insert_recheck_request_if_needed() { >> + local recheck_instance="$1" >> + local recheck_project="$2" >> + local recheck_msgid="$3" >> + local recheck_requested_by="$4" >> + local recheck_series="$5" >> + local recheck_patch="$6" >> + >> + if ! echo "select * from recheck_requests where recheck_message_id=\"$recheck_msgid\";" | series_db_execute | grep $recheck_msgid >/dev/null 2>&1; then >> + echo "INSERT INTO recheck_requests (recheck_message_id, recheck_requested_by, recheck_series, recheck_patch, patchwork_instance, patchwork_project, recheck_sync) values (\"$recheck_msgid\", \"$recheck_requested_by\", \"$recheck_series\", $recheck_patch, \"$recheck_instance\", \"$recheck_project\", 0);" | series_db_execute >> + fi >> +} >> + >> +function get_recheck_request() { >> + local recheck_instance="$1" >> + local recheck_project="$2" >> + local recheck_msgid="$3" >> + local recheck_requested_by="$4" >> + local recheck_series="$5" >> + local recheck_state="$6" >> + >> + echo "select * from recheck_requests where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\" and recheck_message_id=\"$recheck_msgid\" and recheck_sync=$recheck_state;" | series_db_execute >> +} >> + >> +function set_recheck_request_state() { >> + local recheck_instance="$1" >> + local recheck_project="$2" >> + local recheck_msgid="$3" >> + local recheck_requested_by="$4" >> + local recheck_series="$5" >> + local recheck_state="$6" >> + >> + echo "UPDATE recheck_requests set recheck_sync=$recheck_state where patchwork_instance=\"$recheck_instance\" and patchwork_project=\"$recheck_project\" and recheck_requested_by=\"$recheck_requested_by\" and recheck_series=\"$recheck_series\";" | series_db_execute >> +} >> -- >> 2.41.0 >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC v2 3/3] github: add a tool for restarting checks 2023-11-07 20:31 [RFC v2 0/3] Add a recheck framework to pw-ci Aaron Conole 2023-11-07 20:31 ` [RFC v2 1/3] pw_mon: improve command line options Aaron Conole 2023-11-07 20:31 ` [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments Aaron Conole @ 2023-11-07 20:31 ` Aaron Conole 2023-11-17 16:47 ` Michael Santana 2 siblings, 1 reply; 13+ messages in thread From: Aaron Conole @ 2023-11-07 20:31 UTC (permalink / raw) To: ci Cc: Michael Santana, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara The recheck framework can track specific recheck labels and track a state for them. Add a tool that will restart github workflow runs and mark the git build table to check for a repoll. This will allow existing monitor tools to re-poll the workflow and report rerun results. Signed-off-by: Aaron Conole <aconole@redhat.com> --- github_restart | 141 +++++++++++++++++++++++++++++++++++++++++++++++ series_db_lib.sh | 16 ++++++ 2 files changed, 157 insertions(+) create mode 100755 github_restart diff --git a/github_restart b/github_restart new file mode 100755 index 0000000..5ba9677 --- /dev/null +++ b/github_restart @@ -0,0 +1,141 @@ +#!/bin/bash +# SPDX-Identifier: gpl-2.0-or-later +# Copyright (C) 2023, Red Hat, Inc. +# +# Restarts a github job run. This can be used in conjunction with +# the recheck requests to provide the ability for a user to restart +# a test - in case the workflow is suspected of having a spurious run. +# +# Licensed under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. You may obtain a copy of the +# license at +# +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +wait_start="no" + +while [ "$1" != "" ]; do + if echo "$1" | grep -q -s -E ^--pw-project= ; then + pw_project=$(echo "$1" | sed s/^--pw-project=//) + shift + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) + shift + elif echo "$1" | grep -q -s -E ^--pw-credentials= ; then + pw_credential=$(echo "$1" | sed s/^--pw-credentials=//) + shift + elif echo "$1" | grep -q -s -E ^--series-id= ; then + series_id=$(echo "$1" | sed s/^--series-id=//) + shift + elif echo "$1" | grep -q -s -E ^--wait-start ; then + wait_start="yes" + if echo "$1" | grep -q -s -E ^--wait-start= ; then + wait_start=$(echo "$1" | sed s/^--wait-start=//) + fi + shift + elif echo "$1" | grep -q -s -E ^--github-token= ; then + github_token=$(echo "$1" | sed s/^--github-token=//) + shift + elif echo "$1" | grep -q -s -E ^--repository= ; then + reponame=$(echo "$1" | sed s/^--repository=//) + shift + elif echo "$1" | grep -q -s -E ^--run-id= ; then + runid=$(echo "$1" | sed s/^--repository=//) + shift + elif echo "$1" | grep -q -s -E ^--sha= ; then + sha=$(echo "$1" | sed s/^--sha=//) + shift + elif echo "$1" | grep -q -s -E ^--workflow= ; then + workflow=$(echo "$1" | sed s/^--workflow=//) + shift + elif echo "$1" | grep -q -s -E ^--help ; then + echo "github restarting script" + echo "$0: args" + echo " --pw-project=<proj> Project name" + echo " --pw-instance=<inst url> URL for pw" + echo " --series-id=id Series ID for reference" + echo " --github-token=token Token for github" + echo " --wait-start[=yes|no] Wait for the remote to start" + echo " --repository=repo Repository name (ex foo/bar)" + echo " --run-id=id run ID" + echo " --workflow=workflow Workflow name" + echo " --sha=commit Commit sha" + echo "" + exit 0 + else + echo "Unknown option: '$1'" >&2 + echo "Rerun with --help for details" >&2 + exit 1 + fi +done + +source $(dirname $0)/series_db_lib.sh + +if [ "X$wait_start" != "Xno" -a "X$wait_start" != "Xyes" ]; then + echo "Unrecognized '$wait_start' argument to --wait-start=" >&2 + echo "valid values are 'yes' or 'no'." >&2 + exit 1 +fi + +if [ "X$github_token" == "X" ]; then + echo "Please set a github API token." >&2 + echo "Use --help for more info." >&2 + exit 1 +fi + +if [ "X$reponame" == "X" ]; then + echo "Please set a repository (ie: '--repository=owner/repo')." >&2 + echo "Use --help for more info." >&2 + exit 1 +fi + +AUTH="Authorization: token ${github_token}" +APP="Accept: application/vnd.github.v3+json" + +if [ "X$runid" == "X" ]; then + + # lookup the runs based on the shasum + + if [ "X$sha" == "X" ]; then + echo "Need a runid or shasum to key off." >&2 + echo "See --help for more details." >&2 + exit 1 + fi + + comma="" + for job in $(curl -s -S -H "${AUTH}" -H "${APP}" \ + "https://api.github.com/repos/${reponame}/actions/runs?head_sha=${sha}" | \ + jq -rc '.workflow_runs[].id') + do + runid="${comma}${job}" + comma="," + done +fi + +echo -n "{\"results\":[" +comma="" +for job in $(echo "$runid" | sed 's/,/ /'); do + result=$(curl -s -X POST -L -S -H "${AUTH}" -H "${APP}" \ + "https://api.github.com/repos/${reponame}/actions/runs/$job/rerun") + msg=$(echo "$result" | jq -rc '.message') + + echo -n "$comma{\"run\":$job,\"result\":" + if [ "X$msg" == "Xnull" ]; then + echo -n "\"sent\"" + if [ "X$series_id" != "X" ]; then + echo -n ",\"gap_sync\":\"reset\"" + set_unsynced_for_series "$series_id" "$pw_instance" "gap_sync" + fi + else + echo -n "\"err\",\"error\":\"$msg\"" + fi + echo -n "}" +done +echo "]}" diff --git a/series_db_lib.sh b/series_db_lib.sh index ca33c1f..3f052ad 100644 --- a/series_db_lib.sh +++ b/series_db_lib.sh @@ -382,6 +382,14 @@ function set_synced_for_series() { echo "update git_builds set gap_sync=1, obs_sync=1 where patchwork_instance=\"$instance\" and series_id=$series_id;" | series_db_execute } +function set_unsynced_for_series() { + local series_id="$1" + local instance="$2" + local ci_instance="$3" + + echo "update git_builds set $ci_instance=0 where patchwork_instance=\"$instance\" and series_id=$series_id;" | series_db_execute +} + function insert_commit() { local series_id="$1" local patch_id="$2" @@ -407,6 +415,14 @@ function get_patch_id_by_series_id_and_sha() { echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute } +function get_sha_for_series_id_and_patch() { + local series_id="$1" + local patch_id="$2" + local instance="$3" + + echo "select sha from git_builds where patchwork_instance=\"$instance\" and series_id=\"$series_id\" and patch_id=\"$patch_id\"" | series_db_execute +} + function get_recheck_requests_by_project() { local recheck_instance="$1" local recheck_project="$2" -- 2.41.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 3/3] github: add a tool for restarting checks 2023-11-07 20:31 ` [RFC v2 3/3] github: add a tool for restarting checks Aaron Conole @ 2023-11-17 16:47 ` Michael Santana 2023-11-17 19:31 ` Aaron Conole 0 siblings, 1 reply; 13+ messages in thread From: Michael Santana @ 2023-11-17 16:47 UTC (permalink / raw) To: Aaron Conole Cc: ci, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara On Tue, Nov 7, 2023 at 3:32 PM Aaron Conole <aconole@redhat.com> wrote: > > The recheck framework can track specific recheck labels and track a > state for them. Add a tool that will restart github workflow runs > and mark the git build table to check for a repoll. This will allow > existing monitor tools to re-poll the workflow and report rerun > results. > > Signed-off-by: Aaron Conole <aconole@redhat.com> Acked-by: Michael Santana <msantana@redhat.com> > --- > github_restart | 141 +++++++++++++++++++++++++++++++++++++++++++++++ > series_db_lib.sh | 16 ++++++ > 2 files changed, 157 insertions(+) > create mode 100755 github_restart > > diff --git a/github_restart b/github_restart > new file mode 100755 > index 0000000..5ba9677 > --- /dev/null > +++ b/github_restart > @@ -0,0 +1,141 @@ > +#!/bin/bash > +# SPDX-Identifier: gpl-2.0-or-later > +# Copyright (C) 2023, Red Hat, Inc. > +# > +# Restarts a github job run. This can be used in conjunction with > +# the recheck requests to provide the ability for a user to restart > +# a test - in case the workflow is suspected of having a spurious run. > +# > +# Licensed under the terms of the GNU General Public License as published > +# by the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. You may obtain a copy of the > +# license at > +# > +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html > +# > +# Unless required by applicable law or agreed to in writing, software > +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT > +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the > +# License for the specific language governing permissions and limitations > +# under the License. > + > +wait_start="no" > + > +while [ "$1" != "" ]; do > + if echo "$1" | grep -q -s -E ^--pw-project= ; then > + pw_project=$(echo "$1" | sed s/^--pw-project=//) > + shift > + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then > + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) > + shift > + elif echo "$1" | grep -q -s -E ^--pw-credentials= ; then > + pw_credential=$(echo "$1" | sed s/^--pw-credentials=//) > + shift > + elif echo "$1" | grep -q -s -E ^--series-id= ; then > + series_id=$(echo "$1" | sed s/^--series-id=//) > + shift > + elif echo "$1" | grep -q -s -E ^--wait-start ; then > + wait_start="yes" > + if echo "$1" | grep -q -s -E ^--wait-start= ; then > + wait_start=$(echo "$1" | sed s/^--wait-start=//) > + fi > + shift > + elif echo "$1" | grep -q -s -E ^--github-token= ; then > + github_token=$(echo "$1" | sed s/^--github-token=//) > + shift > + elif echo "$1" | grep -q -s -E ^--repository= ; then > + reponame=$(echo "$1" | sed s/^--repository=//) > + shift > + elif echo "$1" | grep -q -s -E ^--run-id= ; then > + runid=$(echo "$1" | sed s/^--repository=//) > + shift > + elif echo "$1" | grep -q -s -E ^--sha= ; then > + sha=$(echo "$1" | sed s/^--sha=//) > + shift > + elif echo "$1" | grep -q -s -E ^--workflow= ; then > + workflow=$(echo "$1" | sed s/^--workflow=//) > + shift > + elif echo "$1" | grep -q -s -E ^--help ; then > + echo "github restarting script" > + echo "$0: args" > + echo " --pw-project=<proj> Project name" > + echo " --pw-instance=<inst url> URL for pw" > + echo " --series-id=id Series ID for reference" > + echo " --github-token=token Token for github" > + echo " --wait-start[=yes|no] Wait for the remote to start" > + echo " --repository=repo Repository name (ex foo/bar)" > + echo " --run-id=id run ID" > + echo " --workflow=workflow Workflow name" > + echo " --sha=commit Commit sha" > + echo "" > + exit 0 > + else > + echo "Unknown option: '$1'" >&2 > + echo "Rerun with --help for details" >&2 > + exit 1 > + fi > +done This entire block makes me feel like maybe we should switch to python :) > + > +source $(dirname $0)/series_db_lib.sh > + > +if [ "X$wait_start" != "Xno" -a "X$wait_start" != "Xyes" ]; then > + echo "Unrecognized '$wait_start' argument to --wait-start=" >&2 > + echo "valid values are 'yes' or 'no'." >&2 > + exit 1 > +fi > + > +if [ "X$github_token" == "X" ]; then > + echo "Please set a github API token." >&2 > + echo "Use --help for more info." >&2 > + exit 1 > +fi > + > +if [ "X$reponame" == "X" ]; then > + echo "Please set a repository (ie: '--repository=owner/repo')." >&2 > + echo "Use --help for more info." >&2 > + exit 1 > +fi > + > +AUTH="Authorization: token ${github_token}" > +APP="Accept: application/vnd.github.v3+json" > + > +if [ "X$runid" == "X" ]; then > + > + # lookup the runs based on the shasum > + > + if [ "X$sha" == "X" ]; then > + echo "Need a runid or shasum to key off." >&2 > + echo "See --help for more details." >&2 > + exit 1 > + fi > + > + comma="" > + for job in $(curl -s -S -H "${AUTH}" -H "${APP}" \ > + "https://api.github.com/repos/${reponame}/actions/runs?head_sha=${sha}" | \ > + jq -rc '.workflow_runs[].id') > + do > + runid="${comma}${job}" > + comma="," > + done > +fi > + > +echo -n "{\"results\":[" > +comma="" > +for job in $(echo "$runid" | sed 's/,/ /'); do > + result=$(curl -s -X POST -L -S -H "${AUTH}" -H "${APP}" \ > + "https://api.github.com/repos/${reponame}/actions/runs/$job/rerun") Okay! > + msg=$(echo "$result" | jq -rc '.message') > + > + echo -n "$comma{\"run\":$job,\"result\":" > + if [ "X$msg" == "Xnull" ]; then > + echo -n "\"sent\"" > + if [ "X$series_id" != "X" ]; then > + echo -n ",\"gap_sync\":\"reset\"" > + set_unsynced_for_series "$series_id" "$pw_instance" "gap_sync" > + fi > + else > + echo -n "\"err\",\"error\":\"$msg\"" > + fi > + echo -n "}" > +done > +echo "]}" > diff --git a/series_db_lib.sh b/series_db_lib.sh > index ca33c1f..3f052ad 100644 > --- a/series_db_lib.sh > +++ b/series_db_lib.sh > @@ -382,6 +382,14 @@ function set_synced_for_series() { > echo "update git_builds set gap_sync=1, obs_sync=1 where patchwork_instance=\"$instance\" and series_id=$series_id;" | series_db_execute > } > > +function set_unsynced_for_series() { > + local series_id="$1" > + local instance="$2" > + local ci_instance="$3" > + > + echo "update git_builds set $ci_instance=0 where patchwork_instance=\"$instance\" and series_id=$series_id;" | series_db_execute > +} > + > function insert_commit() { > local series_id="$1" > local patch_id="$2" > @@ -407,6 +415,14 @@ function get_patch_id_by_series_id_and_sha() { > echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute > } > > +function get_sha_for_series_id_and_patch() { Is this function being used? > + local series_id="$1" > + local patch_id="$2" > + local instance="$3" > + > + echo "select sha from git_builds where patchwork_instance=\"$instance\" and series_id=\"$series_id\" and patch_id=\"$patch_id\"" | series_db_execute > +} > + > function get_recheck_requests_by_project() { > local recheck_instance="$1" > local recheck_project="$2" > -- > 2.41.0 > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 3/3] github: add a tool for restarting checks 2023-11-17 16:47 ` Michael Santana @ 2023-11-17 19:31 ` Aaron Conole 2023-11-17 22:20 ` Michael Santana 0 siblings, 1 reply; 13+ messages in thread From: Aaron Conole @ 2023-11-17 19:31 UTC (permalink / raw) To: Michael Santana Cc: ci, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara Michael Santana <msantana@redhat.com> writes: > On Tue, Nov 7, 2023 at 3:32 PM Aaron Conole <aconole@redhat.com> wrote: >> >> The recheck framework can track specific recheck labels and track a >> state for them. Add a tool that will restart github workflow runs >> and mark the git build table to check for a repoll. This will allow >> existing monitor tools to re-poll the workflow and report rerun >> results. >> >> Signed-off-by: Aaron Conole <aconole@redhat.com> > Acked-by: Michael Santana <msantana@redhat.com> Thanks. >> --- >> github_restart | 141 +++++++++++++++++++++++++++++++++++++++++++++++ >> series_db_lib.sh | 16 ++++++ >> 2 files changed, 157 insertions(+) >> create mode 100755 github_restart >> >> diff --git a/github_restart b/github_restart >> new file mode 100755 >> index 0000000..5ba9677 >> --- /dev/null >> +++ b/github_restart >> @@ -0,0 +1,141 @@ >> +#!/bin/bash >> +# SPDX-Identifier: gpl-2.0-or-later >> +# Copyright (C) 2023, Red Hat, Inc. >> +# >> +# Restarts a github job run. This can be used in conjunction with >> +# the recheck requests to provide the ability for a user to restart >> +# a test - in case the workflow is suspected of having a spurious run. >> +# >> +# Licensed under the terms of the GNU General Public License as published >> +# by the Free Software Foundation; either version 2 of the License, or >> +# (at your option) any later version. You may obtain a copy of the >> +# license at >> +# >> +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html >> +# >> +# Unless required by applicable law or agreed to in writing, software >> +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT >> +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the >> +# License for the specific language governing permissions and limitations >> +# under the License. >> + >> +wait_start="no" >> + >> +while [ "$1" != "" ]; do >> + if echo "$1" | grep -q -s -E ^--pw-project= ; then >> + pw_project=$(echo "$1" | sed s/^--pw-project=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then >> + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--pw-credentials= ; then >> + pw_credential=$(echo "$1" | sed s/^--pw-credentials=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--series-id= ; then >> + series_id=$(echo "$1" | sed s/^--series-id=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--wait-start ; then >> + wait_start="yes" >> + if echo "$1" | grep -q -s -E ^--wait-start= ; then >> + wait_start=$(echo "$1" | sed s/^--wait-start=//) >> + fi >> + shift >> + elif echo "$1" | grep -q -s -E ^--github-token= ; then >> + github_token=$(echo "$1" | sed s/^--github-token=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--repository= ; then >> + reponame=$(echo "$1" | sed s/^--repository=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--run-id= ; then >> + runid=$(echo "$1" | sed s/^--repository=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--sha= ; then >> + sha=$(echo "$1" | sed s/^--sha=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--workflow= ; then >> + workflow=$(echo "$1" | sed s/^--workflow=//) >> + shift >> + elif echo "$1" | grep -q -s -E ^--help ; then >> + echo "github restarting script" >> + echo "$0: args" >> + echo " --pw-project=<proj> Project name" >> + echo " --pw-instance=<inst url> URL for pw" >> + echo " --series-id=id Series ID for reference" >> + echo " --github-token=token Token for github" >> + echo " --wait-start[=yes|no] Wait for the remote to start" >> + echo " --repository=repo Repository name (ex foo/bar)" >> + echo " --run-id=id run ID" >> + echo " --workflow=workflow Workflow name" >> + echo " --sha=commit Commit sha" >> + echo "" >> + exit 0 >> + else >> + echo "Unknown option: '$1'" >&2 >> + echo "Rerun with --help for details" >&2 >> + exit 1 >> + fi >> +done > This entire block makes me feel like maybe we should switch to python :) Agreed. We are on shell scripts for the time being, but a good effort would be to re-do things in python and use better frameworks for everything (for example, passing data between scripts with json rather than the sqlite output strings directly). >> + >> +source $(dirname $0)/series_db_lib.sh >> + >> +if [ "X$wait_start" != "Xno" -a "X$wait_start" != "Xyes" ]; then >> + echo "Unrecognized '$wait_start' argument to --wait-start=" >&2 >> + echo "valid values are 'yes' or 'no'." >&2 >> + exit 1 >> +fi >> + >> +if [ "X$github_token" == "X" ]; then >> + echo "Please set a github API token." >&2 >> + echo "Use --help for more info." >&2 >> + exit 1 >> +fi >> + >> +if [ "X$reponame" == "X" ]; then >> + echo "Please set a repository (ie: '--repository=owner/repo')." >&2 >> + echo "Use --help for more info." >&2 >> + exit 1 >> +fi >> + >> +AUTH="Authorization: token ${github_token}" >> +APP="Accept: application/vnd.github.v3+json" >> + >> +if [ "X$runid" == "X" ]; then >> + >> + # lookup the runs based on the shasum >> + >> + if [ "X$sha" == "X" ]; then >> + echo "Need a runid or shasum to key off." >&2 >> + echo "See --help for more details." >&2 >> + exit 1 >> + fi >> + >> + comma="" >> + for job in $(curl -s -S -H "${AUTH}" -H "${APP}" \ >> + >> "https://api.github.com/repos/${reponame}/actions/runs?head_sha=${sha}" >> | \ >> + jq -rc '.workflow_runs[].id') >> + do >> + runid="${comma}${job}" >> + comma="," >> + done >> +fi >> + >> +echo -n "{\"results\":[" >> +comma="" >> +for job in $(echo "$runid" | sed 's/,/ /'); do >> + result=$(curl -s -X POST -L -S -H "${AUTH}" -H "${APP}" \ >> + "https://api.github.com/repos/${reponame}/actions/runs/$job/rerun") > Okay! >> + msg=$(echo "$result" | jq -rc '.message') >> + >> + echo -n "$comma{\"run\":$job,\"result\":" >> + if [ "X$msg" == "Xnull" ]; then >> + echo -n "\"sent\"" >> + if [ "X$series_id" != "X" ]; then >> + echo -n ",\"gap_sync\":\"reset\"" >> + set_unsynced_for_series "$series_id" "$pw_instance" "gap_sync" >> + fi >> + else >> + echo -n "\"err\",\"error\":\"$msg\"" >> + fi >> + echo -n "}" >> +done >> +echo "]}" >> diff --git a/series_db_lib.sh b/series_db_lib.sh >> index ca33c1f..3f052ad 100644 >> --- a/series_db_lib.sh >> +++ b/series_db_lib.sh >> @@ -382,6 +382,14 @@ function set_synced_for_series() { >> echo "update git_builds set gap_sync=1, obs_sync=1 where patchwork_instance=\"$instance\" and series_id=$series_id;" | series_db_execute >> } >> >> +function set_unsynced_for_series() { >> + local series_id="$1" >> + local instance="$2" >> + local ci_instance="$3" >> + >> + echo "update git_builds set $ci_instance=0 where patchwork_instance=\"$instance\" and series_id=$series_id;" | series_db_execute >> +} >> + >> function insert_commit() { >> local series_id="$1" >> local patch_id="$2" >> @@ -407,6 +415,14 @@ function get_patch_id_by_series_id_and_sha() { >> echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute >> } >> >> +function get_sha_for_series_id_and_patch() { > Is this function being used? Yes - but it should have appeared in 2/3 rather than here in 3/3. I'll fix it before applying things and I plan to send a PATCH series out with those changes as well. >> + local series_id="$1" >> + local patch_id="$2" >> + local instance="$3" >> + >> + echo "select sha from git_builds where patchwork_instance=\"$instance\" and series_id=\"$series_id\" and patch_id=\"$patch_id\"" | series_db_execute >> +} >> + >> function get_recheck_requests_by_project() { >> local recheck_instance="$1" >> local recheck_project="$2" >> -- >> 2.41.0 >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC v2 3/3] github: add a tool for restarting checks 2023-11-17 19:31 ` Aaron Conole @ 2023-11-17 22:20 ` Michael Santana 0 siblings, 0 replies; 13+ messages in thread From: Michael Santana @ 2023-11-17 22:20 UTC (permalink / raw) To: Aaron Conole Cc: ci, David Marchand, Thomas Monjalon, Patrick Robb, Dumitru Ceara On Fri, Nov 17, 2023 at 2:31 PM Aaron Conole <aconole@redhat.com> wrote: > > Michael Santana <msantana@redhat.com> writes: > > > On Tue, Nov 7, 2023 at 3:32 PM Aaron Conole <aconole@redhat.com> wrote: > >> > >> The recheck framework can track specific recheck labels and track a > >> state for them. Add a tool that will restart github workflow runs > >> and mark the git build table to check for a repoll. This will allow > >> existing monitor tools to re-poll the workflow and report rerun > >> results. > >> > >> Signed-off-by: Aaron Conole <aconole@redhat.com> > > Acked-by: Michael Santana <msantana@redhat.com> > > Thanks. > > >> --- > >> github_restart | 141 +++++++++++++++++++++++++++++++++++++++++++++++ > >> series_db_lib.sh | 16 ++++++ > >> 2 files changed, 157 insertions(+) > >> create mode 100755 github_restart > >> > >> diff --git a/github_restart b/github_restart > >> new file mode 100755 > >> index 0000000..5ba9677 > >> --- /dev/null > >> +++ b/github_restart > >> @@ -0,0 +1,141 @@ > >> +#!/bin/bash > >> +# SPDX-Identifier: gpl-2.0-or-later > >> +# Copyright (C) 2023, Red Hat, Inc. > >> +# > >> +# Restarts a github job run. This can be used in conjunction with > >> +# the recheck requests to provide the ability for a user to restart > >> +# a test - in case the workflow is suspected of having a spurious run. > >> +# > >> +# Licensed under the terms of the GNU General Public License as published > >> +# by the Free Software Foundation; either version 2 of the License, or > >> +# (at your option) any later version. You may obtain a copy of the > >> +# license at > >> +# > >> +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.html > >> +# > >> +# Unless required by applicable law or agreed to in writing, software > >> +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT > >> +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the > >> +# License for the specific language governing permissions and limitations > >> +# under the License. > >> + > >> +wait_start="no" > >> + > >> +while [ "$1" != "" ]; do > >> + if echo "$1" | grep -q -s -E ^--pw-project= ; then > >> + pw_project=$(echo "$1" | sed s/^--pw-project=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--pw-instance= ; then > >> + pw_instance=$(echo "$1" | sed s/^--pw-instance=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--pw-credentials= ; then > >> + pw_credential=$(echo "$1" | sed s/^--pw-credentials=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--series-id= ; then > >> + series_id=$(echo "$1" | sed s/^--series-id=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--wait-start ; then > >> + wait_start="yes" > >> + if echo "$1" | grep -q -s -E ^--wait-start= ; then > >> + wait_start=$(echo "$1" | sed s/^--wait-start=//) > >> + fi > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--github-token= ; then > >> + github_token=$(echo "$1" | sed s/^--github-token=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--repository= ; then > >> + reponame=$(echo "$1" | sed s/^--repository=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--run-id= ; then > >> + runid=$(echo "$1" | sed s/^--repository=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--sha= ; then > >> + sha=$(echo "$1" | sed s/^--sha=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--workflow= ; then > >> + workflow=$(echo "$1" | sed s/^--workflow=//) > >> + shift > >> + elif echo "$1" | grep -q -s -E ^--help ; then > >> + echo "github restarting script" > >> + echo "$0: args" > >> + echo " --pw-project=<proj> Project name" > >> + echo " --pw-instance=<inst url> URL for pw" > >> + echo " --series-id=id Series ID for reference" > >> + echo " --github-token=token Token for github" > >> + echo " --wait-start[=yes|no] Wait for the remote to start" > >> + echo " --repository=repo Repository name (ex foo/bar)" > >> + echo " --run-id=id run ID" > >> + echo " --workflow=workflow Workflow name" > >> + echo " --sha=commit Commit sha" > >> + echo "" > >> + exit 0 > >> + else > >> + echo "Unknown option: '$1'" >&2 > >> + echo "Rerun with --help for details" >&2 > >> + exit 1 > >> + fi > >> +done > > This entire block makes me feel like maybe we should switch to python :) > > Agreed. We are on shell scripts for the time being, but a good effort > would be to re-do things in python and use better frameworks for > everything (for example, passing data between scripts with json rather > than the sqlite output strings directly). I wonder how useful ChatGPT and its siblings would be at converting all of our shell scripts into python :P > > >> + > >> +source $(dirname $0)/series_db_lib.sh > >> + > >> +if [ "X$wait_start" != "Xno" -a "X$wait_start" != "Xyes" ]; then > >> + echo "Unrecognized '$wait_start' argument to --wait-start=" >&2 > >> + echo "valid values are 'yes' or 'no'." >&2 > >> + exit 1 > >> +fi > >> + > >> +if [ "X$github_token" == "X" ]; then > >> + echo "Please set a github API token." >&2 > >> + echo "Use --help for more info." >&2 > >> + exit 1 > >> +fi > >> + > >> +if [ "X$reponame" == "X" ]; then > >> + echo "Please set a repository (ie: '--repository=owner/repo')." >&2 > >> + echo "Use --help for more info." >&2 > >> + exit 1 > >> +fi > >> + > >> +AUTH="Authorization: token ${github_token}" > >> +APP="Accept: application/vnd.github.v3+json" > >> + > >> +if [ "X$runid" == "X" ]; then > >> + > >> + # lookup the runs based on the shasum > >> + > >> + if [ "X$sha" == "X" ]; then > >> + echo "Need a runid or shasum to key off." >&2 > >> + echo "See --help for more details." >&2 > >> + exit 1 > >> + fi > >> + > >> + comma="" > >> + for job in $(curl -s -S -H "${AUTH}" -H "${APP}" \ > >> + > >> "https://api.github.com/repos/${reponame}/actions/runs?head_sha=${sha}" > >> | \ > >> + jq -rc '.workflow_runs[].id') > >> + do > >> + runid="${comma}${job}" > >> + comma="," > >> + done > >> +fi > >> + > >> +echo -n "{\"results\":[" > >> +comma="" > >> +for job in $(echo "$runid" | sed 's/,/ /'); do > >> + result=$(curl -s -X POST -L -S -H "${AUTH}" -H "${APP}" \ > >> + "https://api.github.com/repos/${reponame}/actions/runs/$job/rerun") > > Okay! > >> + msg=$(echo "$result" | jq -rc '.message') > >> + > >> + echo -n "$comma{\"run\":$job,\"result\":" > >> + if [ "X$msg" == "Xnull" ]; then > >> + echo -n "\"sent\"" > >> + if [ "X$series_id" != "X" ]; then > >> + echo -n ",\"gap_sync\":\"reset\"" > >> + set_unsynced_for_series "$series_id" "$pw_instance" "gap_sync" > >> + fi > >> + else > >> + echo -n "\"err\",\"error\":\"$msg\"" > >> + fi > >> + echo -n "}" > >> +done > >> +echo "]}" > >> diff --git a/series_db_lib.sh b/series_db_lib.sh > >> index ca33c1f..3f052ad 100644 > >> --- a/series_db_lib.sh > >> +++ b/series_db_lib.sh > >> @@ -382,6 +382,14 @@ function set_synced_for_series() { > >> echo "update git_builds set gap_sync=1, obs_sync=1 where patchwork_instance=\"$instance\" and series_id=$series_id;" | series_db_execute > >> } > >> > >> +function set_unsynced_for_series() { > >> + local series_id="$1" > >> + local instance="$2" > >> + local ci_instance="$3" > >> + > >> + echo "update git_builds set $ci_instance=0 where patchwork_instance=\"$instance\" and series_id=$series_id;" | series_db_execute > >> +} > >> + > >> function insert_commit() { > >> local series_id="$1" > >> local patch_id="$2" > >> @@ -407,6 +415,14 @@ function get_patch_id_by_series_id_and_sha() { > >> echo "select patch_id from git_builds where patchwork_instance=\"$instance\" and series_id=$series_id and sha=\"$sha\";" | series_db_execute > >> } > >> > >> +function get_sha_for_series_id_and_patch() { > > Is this function being used? > > Yes - but it should have appeared in 2/3 rather than here in 3/3. I'll > fix it before applying things and I plan to send a PATCH series out with > those changes as well. > > >> + local series_id="$1" > >> + local patch_id="$2" > >> + local instance="$3" > >> + > >> + echo "select sha from git_builds where patchwork_instance=\"$instance\" and series_id=\"$series_id\" and patch_id=\"$patch_id\"" | series_db_execute > >> +} > >> + > >> function get_recheck_requests_by_project() { > >> local recheck_instance="$1" > >> local recheck_project="$2" > >> -- > >> 2.41.0 > >> > ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2023-11-17 22:20 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-11-07 20:31 [RFC v2 0/3] Add a recheck framework to pw-ci Aaron Conole 2023-11-07 20:31 ` [RFC v2 1/3] pw_mon: improve command line options Aaron Conole 2023-11-17 16:26 ` Michael Santana 2023-11-17 19:28 ` Aaron Conole 2023-11-07 20:31 ` [RFC v2 2/3] recheck: Add a recheck parser for patchwork comments Aaron Conole 2023-11-09 20:45 ` Dumitru Ceara 2023-11-10 14:05 ` Aaron Conole 2023-11-17 16:35 ` Michael Santana 2023-11-17 19:28 ` Aaron Conole 2023-11-07 20:31 ` [RFC v2 3/3] github: add a tool for restarting checks Aaron Conole 2023-11-17 16:47 ` Michael Santana 2023-11-17 19:31 ` Aaron Conole 2023-11-17 22:20 ` Michael Santana
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).