diff --git a/.github/workflows/add-backport-label.yaml b/.github/workflows/add-backport-label.yaml index e775fda0e6..5f033f3cd2 100644 --- a/.github/workflows/add-backport-label.yaml +++ b/.github/workflows/add-backport-label.yaml @@ -19,18 +19,11 @@ jobs: if: ${{ github.event.label.name != 'auto-backport' }} runs-on: ubuntu-latest steps: - - name: Checkout code to allow hub to communicate with the project + - name: Checkout code to get gh-utils script if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }} uses: actions/checkout@v4 - - name: Install hub extension script - run: | - pushd $(mktemp -d) &>/dev/null - git clone --single-branch --depth 1 "https://github.com/kata-containers/.github" && cd .github/scripts - sudo install hub-util.sh /usr/local/bin - popd &>/dev/null - - - name: Determine whether to add label + - name: Determine whether to add label if: ${{ !contains(github.event.pull_request.labels.*.name, 'force-skip-ci') }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -38,25 +31,19 @@ jobs: id: add_label run: | pr=${{ github.event.pull_request.number }} - linked_issue_urls=$(hub-util.sh \ + linked_issues=$(./ci/gh-util.sh \ list-issues-for-pr "$pr" |\ - grep -v "^\#" |\ - cut -d';' -f3 || true) - [ -z "$linked_issue_urls" ] && { + grep -v "^\#" || true) + [ -z "${linked_issues}" ] && { echo "::error::No linked issues for PR $pr" exit 1 } has_bug=false - for issue_url in $(echo "$linked_issue_urls") + for issue in $(echo "$linked_issues") do - issue=$(echo "$issue_url"| awk -F\/ '{print $NF}' || true) - [ -z "$issue" ] && { - echo "::error::Cannot determine issue number from $issue_url for PR $pr" - exit 1 - } - labels=$(hub-util.sh list-labels-for-issue "$issue") - - label_names=$(echo $labels | jq -r '.[].name' || true) + labels=$(./ci/gh-util.sh list-labels-for-issue "$issue") + + label_names=$(echo $labels | jq -r '.labels[].name' || true) if [[ "$label_names" =~ "bug" ]]; then has_bug=true break diff --git a/ci/gh-util.sh b/ci/gh-util.sh new file mode 100755 index 0000000000..3ab62b9b81 --- /dev/null +++ b/ci/gh-util.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# Copyright (c) 2020 Intel Corporation +# Copyright (c) 2024 IBM Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +[ -n "${DEBUG:-}" ] && set -o xtrace + +script_name=${0##*/} + +#--------------------------------------------------------------------- + +die() +{ + echo >&2 "$*" + exit 1 +} + +usage() +{ + cat < + list-labels-for-issue + +Options: + + -h Show this help statement. + -r Optional specification. Default: 'kata-containers/kata-containers' + +Examples: + +- List issues for a Pull Request 123 in kata-containers/kata-containers repo + + $ $script_name list-issues-for-pr 123 +EOF +} + +list_issues_for_pr() +{ + local pr="${1:-}" + local repo="${2:-kata-containers/kata-containers}" + + [ -z "$pr" ] && die "need PR" + + local commits=$(gh pr view ${pr} --repo ${repo} --json commits --jq .commits[].messageBody) + + [ -z "$commits" ] && die "cannot determine commits for PR $pr" + + # Extract the issue number(s) from the commits. + # + # This needs to be careful to take account of lines like this: + # + # fixes 99 + # fixes: 77 + # fixes #123. + # Fixes: #1, #234, #5678. + # + # Note the exclusion of lines starting with whitespace which is + # specifically to ignore vendored git log comments, which are whitespace + # indented and in the format: + # + # " " + # + local issues=$(echo "$commits" |\ + egrep -v "^( | )" |\ + egrep -i "fixes:* *(#*[0-9][0-9]*)" |\ + tr ' ' '\n' |\ + grep "[0-9][0-9]*" |\ + sed 's/[.,\#]//g' |\ + sort -nu || true) + + [ -z "$issues" ] && die "cannot determine issues for PR $pr" + + echo "# Issues linked to PR" + echo "#" + echo "# Fields: issue_number" + + local issue + echo "$issues"|while read issue + do + printf "%s\n" "$issue" + done +} + +list_labels_for_issue() +{ + local issue="${1:-}" + + [ -z "$issue" ] && die "need issue number" + + local labels=$(gh issue view ${issue} --repo kata-containers/kata-containers --json labels) + + [ -z "$labels" ] && die "cannot determine labels for issue $issue" + + printf "$labels" +} + +setup() +{ + for cmd in gh jq + do + command -v "$cmd" &>/dev/null || die "need command: $cmd" + done +} + +handle_args() +{ + setup + + local show_all="false" + local opt + + while getopts "ahr:" opt "$@" + do + case "$opt" in + a) show_all="true" ;; + h) usage && exit 0 ;; + r) repo="${OPTARG}" ;; + esac + done + + shift $(($OPTIND - 1)) + + local repo="${repo:-kata-containers/kata-containers}" + local cmd="${1:-}" + + case "$cmd" in + list-issues-for-pr) ;; + list-labels-for-issue) ;; + + "") usage && exit 0 ;; + *) die "invalid command: '$cmd'" ;; + esac + + # Consume the command name + shift + + local issue="" + local pr="" + + case "$cmd" in + list-issues-for-pr) + pr="${1:-}" + + list_issues_for_pr "$pr" "${repo}" + ;; + + list-labels-for-issue) + issue="${1:-}" + + list_labels_for_issue "$issue" + ;; + + *) die "impossible situation: cmd: '$cmd'" ;; + esac + + exit 0 +} + +main() +{ + handle_args "$@" +} + +main "$@"