From 17193af962453a3cfde2d9f25c0fea29e3c91cf3 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 14 Aug 2024 15:54:06 +0200 Subject: [PATCH] CI: On vX.Y-rhel branches, ensure that some downstream Jira issue is linked In the RHEL specific branches we want to ensure that all MRs link to at least one downstream Jira ticket. To do this we add a new test in validate-source similar to the existing pr-should-include-tests. This test only runs on actual pull requests. The syntax for linking to a Jira is "Fixes " or "Fixes: ", followed by one jira links, like so: ``` Fixes https://issues.redhat.com/browse/RHEL-50506 Fixes: https://issues.redhat.com/browse/RHEL-50506 ``` Note: This is the same syntax as for a regular github issue reference. Signed-off-by: Alexander Larsson --- Makefile | 4 + contrib/cirrus/pr-should-link-jira | 79 +++++++++++++++ contrib/cirrus/pr-should-link-jira.t | 146 +++++++++++++++++++++++++++ contrib/cirrus/prebuild.sh | 3 + contrib/cirrus/runner.sh | 3 + 5 files changed, 235 insertions(+) create mode 100755 contrib/cirrus/pr-should-link-jira create mode 100755 contrib/cirrus/pr-should-link-jira.t diff --git a/Makefile b/Makefile index 33d3f61425..37dc51e10b 100644 --- a/Makefile +++ b/Makefile @@ -745,6 +745,10 @@ test-binaries: test/checkseccomp/checkseccomp test/goecho/goecho install.cataton tests-included: contrib/cirrus/pr-should-include-tests +.PHONY: test-jira-links-included +test-jira-links-included: + contrib/cirrus/pr-should-link-jira + .PHONY: tests-expect-exit tests-expect-exit: @if grep -E --line-number 'Expect.*ExitCode' test/e2e/*.go | grep -E -v ', ".*"\)'; then \ diff --git a/contrib/cirrus/pr-should-link-jira b/contrib/cirrus/pr-should-link-jira new file mode 100755 index 0000000000..1f4c7d08df --- /dev/null +++ b/contrib/cirrus/pr-should-link-jira @@ -0,0 +1,79 @@ +#!/bin/bash +# +# Intended for use in CI, for -rhel branches: check git PR, barf if no jira links +# + +ME=$(basename $0) + +set -e + +# Github label which allows overriding this check +OVERRIDE_LABEL="No Jira Link" + +# Only -rhel branches need jira links +BRANCH_REGEX="v.*-rhel" + +LINK_REGEX="Fixes:?[[:space:]]+https://issues.redhat.com/[[:alnum:]/-]*" + +if [[ ! "${DEST_BRANCH}" =~ $BRANCH_REGEX ]]; then + exit 0 +fi + +if [[ "${CIRRUS_CHANGE_MESSAGE}" =~ $LINK_REGEX ]]; then + exit 0 +fi + +# Nope. Only allow if the github 'No Jira Link' label is set +if [[ -z "$CIRRUS_PR" ]]; then + if [[ ! "$CIRRUS_BRANCH" =~ pull ]] || [[ -n "$CIRRUS_TAG" ]]; then + echo "Warning: $ME only intended for use on PRs in CI" + exit 0 + fi + echo "$ME: cannot query github: \$CIRRUS_PR is undefined" >&2 + exit 1 +fi + +if [[ -z "$CIRRUS_REPO_CLONE_TOKEN" ]]; then + echo "$ME: cannot query github: \$CIRRUS_REPO_CLONE_TOKEN is undefined" >&2 + exit 1 +fi + +query="{ + \"query\": \"query { + repository(owner: \\\"containers\\\", name: \\\"podman\\\") { + pullRequest(number: $CIRRUS_PR) { + labels(first: 100) { + nodes { + name + } + } + } + } +}\" +}" + +result=$(curl -s -H "Authorization: bearer $CIRRUS_REPO_CLONE_TOKEN" -H "Accept: application/vnd.github.antiope-preview+json" -H "Content-Type: application/json" -X POST --data @- https://api.github.com/graphql <<<"$query") + +labels=$(jq -r '.data.repository.pullRequest.labels.nodes[]?.name' <<<"$result") + +if grep -F -x -q "$OVERRIDE_LABEL" <<<"$labels"; then + # PR has the label set + exit 0 +fi + +cat <&2 + exit 1 + fi +fi + +############################################################################### +# BEGIN test cases +# + +read -d '\n' msg_no_jira << EndOfText +This is some text +without a jira +EndOfText + +read -d '\n' msg_invalid << EndOfText +This is some text +without a jira +Fixes #42 +More text... +EndOfText + +read -d '\n' msg_jira << EndOfText +This is some text +with a jira +Fixes https://issues.redhat.com/browse/RHEL-50507 +More text... +EndOfText + +read -d '\n' msg_jira2 << EndOfText +This is some text +with a jira +Fixes: https://issues.redhat.com/browse/RHEL-50507 +More text... +EndOfText + +read -d '\n' msg_multiple << EndOfText +This is some text +with multiple jira lines +Fixes https://issues.redhat.com/browse/RHEL-50507 +More text... +Fixes: https://issues.redhat.com/browse/RHEL-50506 +More text... +EndOfText + +# Feel free to add as needed. Syntax is: +# # comments +# +# Where: +# exit status is the expected exit status of the script +# pr pr number (only used to get tag, 0000 if doesn't matter) +# commit message commit message +# dest branch name of branch +# + +tests=" +0 0000 msg_no_jira main not rhel branch, no link, should pass +0 0000 msg_jira main not rhel branch, link, should pass +0 0000 msg_invalid main not rhel branch, invalid link, should pass +0 0000 msg_no_jira v4.9 not rhel branch, no link, should pass +1 23514 msg_no_jira v4.9-rhel no link, no tag, should fail +0 8890 msg_no_jira v4.9-rhel no link, tag, should work +1 23514 msg_invalid v4.9-rhel invalid link, no tag, should fail +0 0000 msg_jira v4.9-rhel link, should work +0 0000 msg_jira2 v4.9-rhel link with colon, should work +0 0000 msg_multiple v4.9-rhel multiple links, should work +" + +# The script we're testing +test_script=$(dirname $0)/$(basename $0 .t) + +# END test cases +############################################################################### +# BEGIN test-script runner and status checker + +function run_test_script() { + local expected_rc=$1 + local testname=$2 + + testnum=$(( testnum + 1 )) + + # DO NOT COMBINE 'local output=...' INTO ONE LINE. If you do, you lose $? + local output + output=$( $test_script ) + local actual_rc=$? + + if [[ $actual_rc != $expected_rc ]]; then + echo "not ok $testnum $testname" + echo "# expected rc $expected_rc" + echo "# actual rc $actual_rc" + if [[ -n "$output" ]]; then + echo "# script output: $output" + fi + rc=1 + else + if [[ $expected_rc == 1 ]]; then + # Confirm we get an error message + if [[ ! "$output" =~ "Please add a reference" ]]; then + echo "not ok $testnum $testname" + echo "# Expected: ~ 'Please add a reference'" + echo "# Actual: $output" + rc=1 + else + echo "ok $testnum $testname - rc=$expected_rc" + fi + else + echo "ok $testnum $testname - rc=$expected_rc" + fi + fi +} + +# END test-script runner and status checker +############################################################################### +# BEGIN test-case parsing + +rc=0 +testnum=0 +tested_override= + +while read expected_rc pr msg branch rest; do + # Skip blank lines + test -z "$expected_rc" && continue + + export DEST_BRANCH=$branch + export CIRRUS_CHANGE_MESSAGE="${!msg}" + export CIRRUS_PR=$pr + + run_test_script $expected_rc "PR $pr $msg $branch - $rest" +done <<<"$tests" + +echo "1..$testnum" +exit $rc + +# END Test-case parsing +############################################################################### diff --git a/contrib/cirrus/prebuild.sh b/contrib/cirrus/prebuild.sh index 8b6a789b1b..65c254f556 100755 --- a/contrib/cirrus/prebuild.sh +++ b/contrib/cirrus/prebuild.sh @@ -62,6 +62,9 @@ if [[ "${DISTRO_NV}" == "$PRIOR_FEDORA_NAME" ]]; then # Tests for lib.sh showrun ${SCRIPT_BASE}/lib.sh.t + # Tests for pr-should-link-jira + showrun ${SCRIPT_BASE}/pr-should-link-jira.t + msg "Checking renovate config." showrun podman run -it \ -v ./.github/renovate.json5:/usr/src/app/renovate.json5:z \ diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh index 88f9abfcec..5c9209221b 100755 --- a/contrib/cirrus/runner.sh +++ b/contrib/cirrus/runner.sh @@ -26,6 +26,9 @@ function _run_validate-source() { # make sure PRs have tests showrun make tests-included + + # make sure PRs have jira links (if needed for branch) + showrun make test-jira-links-included } function _run_unit() {