Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pr-schedule-tests
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ if [ $(echo $CONFIG_LINE | tr ';' '\n' | grep SCRAM_ARCH= | wc -l) -eq 1 ] ; the
echo "CONTEXT_PREFIX=${CONTEXT_PREFIX}" >> $OUTPUT_FILE
echo "PROFILING_WORKFLOWS=${PROFILING_WORKFLOWS}" >> $OUTPUT_FILE
echo "BUILD_VERBOSE=${BUILD_VERBOSE}" >> $OUTPUT_FILE
echo "BUILD_ONLY=${BUILD_ONLY}" >> $OUTPUT_FILE
CMSSW_QUEUE="${RELEASE_QUEUE}"
mark_commit_status_all_prs "${PR_COMMIT_STATUS}" 'pending' -d "Tests scheduled ${RELEASE_FORMAT}/${SCRAM_ARCH}" -u 'https://cmssdt.cern.ch/jenkins/job/ib-run-pr-tests/' || true
COMMIT_STATUS_CONTEXT="unknown/release"
Expand Down
30 changes: 30 additions & 0 deletions pr_testing/test_multiple_prs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ PR_REPO=$(echo ${PULL_REQUEST} | sed 's|#.*||')
PR_NUM=$(echo ${PULL_REQUEST} | md5sum | sed 's| .*||' | cut -c27-33)
UPLOAD_UNIQ_ID=PR-${PR_NUM}/${BUILD_NUMBER}
PR_RESULT_URL="https://cmssdt.cern.ch/SDT/${JENKINS_PREFIX}-artifacts/pull-request-integration/${UPLOAD_UNIQ_ID}"
PR_COMMENT_TEXT_URL="https://cmssdt.cern.ch/SDT/cgi-bin/get_pr_results/${JENKINS_PREFIX}-artifacts/pull-request-integration/${UPLOAD_UNIQ_ID}/pr-result"
NCPU=$(${COMMON}/get_cpu_number.sh)
if [[ $NODE_NAME == *"cms-cmpwg-0"* ]]; then
let NCPU=${NCPU}/2
Expand Down Expand Up @@ -185,6 +186,9 @@ for ex_type in $(echo ${ENABLE_BOT_TESTS} | tr "," " ") ; do
fi
done

if [ "${BUILD_ONLY}" = "true" ] ; then
DO_COMPARISON=false
fi
# ----------
# -- MAIN --
# ----------
Expand Down Expand Up @@ -243,6 +247,12 @@ PR_COMMIT_STATUS="optional"
if $REQUIRED_TEST ; then PR_COMMIT_STATUS="required" ; fi
mark_commit_status_all_prs "${PR_COMMIT_STATUS}" 'success' -d 'OK' -u "${BUILD_URL}"

if [ "${BUILD_ONLY}" = "true" ] ; then
mark_commit_status_all_prs "build_only" "success" -u "${BUILD_URL}" -d 'Only build'
else
mark_commit_status_all_prs "build_only" "success" -u "${BUILD_URL}" -d 'Build and test'
fi

echo -n "**Summary**: ${PR_RESULT_URL}/summary.html" > ${RESULTS_DIR}/09-report.res
CMSSW_VERSION=${RELEASE_FORMAT} $CMS_BOT_DIR/report-pull-request-results GET_BASE_MESSAGE --report-url ${PR_RESULT_URL} \
--commit ${COMMIT} --report-file ${RESULTS_DIR}/09-report.res ${REPORT_OPTS}
Expand Down Expand Up @@ -1325,6 +1335,14 @@ fi

mark_commit_status_all_prs '' 'pending' -u "${BUILD_URL}" -d "Running tests" || true

if [ "$BUILD_ONLY" = "true" ]; then
DO_SHORT_MATRIX=false
DISABLE_GPU_TESTS=true
DO_ADDON_TESTS=false
DO_CRAB_TESTS=false
ENABLE_BOT_TESTS=$(echo $ENABLE_BOT_TESTS | sed -e 's/HLT_P2_TIMING//;s/HLT_P2_INTEGRATION//;s/PROFILING//')
fi

DO_PROFILING=false
DO_GPU_TESTS=false
if [ "X$BUILD_OK" = Xtrue -a "$RUN_TESTS" = "true" ]; then
Expand Down Expand Up @@ -1438,6 +1456,18 @@ for x in REPORT_OPTS BUILD_EXTERNAL DO_DUPLICATE_CHECKS DO_DAS_QUERY DO_TESTS CM
eval echo "$x=\\\"$(echo \$$x)\\\"" >> $WORKSPACE/job.env
done

if [ "${BUILD_ONLY}" = "true" ]; then
if ${ALL_OK} ; then
echo "+1" > comment.txt
else
echo "-1" > comment.txt
fi
echo "" >> comment.txt
curl -L ${PR_COMMENT_TEXT_URL} >> comment.txt
$WORKSPACE/cms-bot/comment-gh-pr.py --repository ${PR_REPO} --pullrequest ${PR_NUMBER} --report-file comment.txt
mark_commit_status_all_prs "${PR_COMMIT_STATUS}" 'success' -u "${BUILD_URL}" -d "Finished" -e
fi

echo "UPLOAD_UNIQ_ID=${UPLOAD_UNIQ_ID}" > $WORKSPACE/test-env.txt
echo "CMSSW_CVMFS_PATH=/cvmfs/cms-ci.cern.ch/week${WEEK_NUM}/${PR_REPO}/${PR_NUMBER}/${BUILD_NUMBER}/${CMSSW_VERSION}" >> $WORKSPACE/test-env.txt
echo "PULL_REQUEST=${PULL_REQUEST}" >> $WORKSPACE/test-env.txt
Expand Down
107 changes: 69 additions & 38 deletions process_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def format(s, **kwds):
cmsorgs="|".join(EXTERNAL_REPOS),
)
TEST_REGEXP = format(
r"^\s*((@|)cmsbuild\s*[,]*\s+|)(please\s*[,]*\s+|)test(\s+workflow(s|)\s+(%(workflow)s(\s*,\s*%(workflow)s|)*)|)(\s+with\s+(%(cms_pr)s(\s*,\s*%(cms_pr)s)*)|)(\s+for\s+%(release_queue)s|)(\s+using\s+full\s+cmssw|\s+using\s+(cms-|)addpkg\s+(%(pkg)s(,%(pkg)s)*)|)\s*$",
r"^\s*((@|)cmsbuild\s*[,]*\s+|)(please\s*[,]*\s+|)(test|build)(\s+workflow(s|)\s+(%(workflow)s(\s*,\s*%(workflow)s|)*)|)(\s+with\s+(%(cms_pr)s(\s*,\s*%(cms_pr)s)*)|)(\s+for\s+%(release_queue)s|)(\s+using\s+full\s+cmssw|\s+using\s+(cms-|)addpkg\s+(%(pkg)s(,%(pkg)s)*)|)\s*$",
workflow=WF_PATTERN,
cms_pr=CMS_PR_PATTERN,
pkg=CMSSW_PACKAGE_PATTERN,
Expand Down Expand Up @@ -358,6 +358,8 @@ def extract_bot_cache(comment_msgs):

data = ""
for comment_msg in comment_msgs:
if not comment_msg.body:
continue
seen_commits_match = REGEX_COMMITS_CACHE.search(comment_msg.body)
if seen_commits_match:
data += seen_commits_match[1]
Expand Down Expand Up @@ -565,9 +567,9 @@ def has_user_emoji(bot_cache, comment, repository, emoji, user):
# github_utils.get_comment_emojis -> https://github.com/PyGithub/PyGithub/blob/v1.56/github/IssueComment.py#L135
emojis = comment.get_reactions()
for x in emojis:
if x["user"]["login"].encode("ascii", "ignore").decode() == user:
e = x["content"]
bot_cache["emoji"][comment_id] = x
if x.user.login.encode("ascii", "ignore").decode() == user:
e = x.content
bot_cache["emoji"][comment_id] = e
break
return e and e == emoji

Expand Down Expand Up @@ -745,19 +747,20 @@ def check_test_cmd(first_line, repo, params):
prs = []
cmssw_que = ""
logger.debug("check_test_cmd: %s", m.groups())
if m.group(6):
wfs = ",".join(set(m.group(6).replace(" ", "").split(",")))
if m.group(11):
prs = get_prs_list_from_string(m.group(11), repo)
if m.group(20):
cmssw_que = m.group(20)
if m.group(25):
if "addpkg" in m.group(25):
params["EXTRA_CMSSW_PACKAGES"] = m.group(27).strip()
build_only = m.group(4) == "build"
if m.group(7):
wfs = ",".join(set(m.group(7).replace(" ", "").split(",")))
if m.group(12):
prs = get_prs_list_from_string(m.group(12), repo)
if m.group(21):
cmssw_que = m.group(21)
if m.group(26):
if "addpkg" in m.group(26):
params["EXTRA_CMSSW_PACKAGES"] = m.group(28).strip()
else:
params["BUILD_FULL_CMSSW"] = "true"
return (True, " ".join(prs), wfs, cmssw_que)
return (False, "", "", "")
return (True, " ".join(prs), wfs, cmssw_que, build_only)
return (False, "", "", "", False)


def get_prs_list_from_string(pr_string="", repo_string=""):
Expand Down Expand Up @@ -1078,6 +1081,7 @@ def process_pr(
ok_too_many_files = False
warned_too_many_files = False
is_draft_pr = False
build_only = False

if issue.pull_request:
pr = repo.get_pull(prId)
Expand Down Expand Up @@ -1665,9 +1669,8 @@ def process_pr(

# Check if the someone asked to trigger the tests
if valid_commenter:
ok, v2, v3, v4 = check_test_cmd(first_line, repository, global_test_params)
ok, v2, v3, v4, v5 = check_test_cmd(first_line, repository, global_test_params)
if ok:
test_comment = comment
abort_test = None
cmssw_prs = v2
extra_wfs = ",".join(sorted(v3.split(",")))
Expand All @@ -1678,16 +1681,25 @@ def process_pr(
elif re.match("^" + ARCH_PATTERN + "$", release_queue):
release_arch = release_queue
release_queue = ""

if v5 and has_user_emoji(bot_cache, comment, repository, "+1", cmsbuild_user):
# test_comment = None
continue

build_only = v5
test_comment = comment
signatures["tests"] = "pending"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iarspider , I do not think this is what we discussed :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really? Then I misunderstood your suggestion.

logger.info(
"Tests requested: %s asked to test this PR with cmssw_prs=%s, release_queue=%s, arch=%s and workflows=%s",
"Tests requested: %s asked to test this PR with cmssw_prs=%s, release_queue=%s, arch=%s and workflows=%s; build_only=%s",
commenter,
cmssw_prs,
release_queue,
release_arch,
extra_wfs,
build_only,
)
logger.debug("Comment message: %s", first_line)
signatures["tests"] = "pending"
continue
elif REGEX_TEST_ABORT.match(first_line) and (signatures["tests"] == "pending"):
abort_test = comment
Expand Down Expand Up @@ -2096,20 +2108,26 @@ def process_pr(
if bot_status or (signatures["tests"] == "pending"):
new_bot_tests = True
trigger_test = True
signatures["tests"] = "started"
if not build_only:
signatures["tests"] = "started"
Copy link
Contributor

@smuzaffar smuzaffar Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iarspider , may be this change is not needed? we override the test labels for build_only any way .... right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

desc = "requested by %s at %s UTC." % (
ensure_ascii(test_comment.user.login),
test_comment.created_at,
)
if not new_bot_tests:
desc = "Old style tests %s" % desc
else:
desc = "Tests %s" % desc
if not build_only:
desc = "Tests %s" % desc
else:
desc = "Build %s" % desc

logger.debug('Create status "%s"', desc)
if not dryRun:
last_commit_obj.create_status(
"success", description=desc, target_url=turl, context=bot_status_name
)
if not build_only:
last_commit_obj.create_status(
"success", description=desc, target_url=turl, context=bot_status_name
)
set_comment_emoji_cache(dryRun, bot_cache, test_comment, repository)
if bot_status:
logger.debug(
Expand All @@ -2124,6 +2142,7 @@ def process_pr(
and bot_status.target_url == turl
and signatures["tests"] == "pending"
and (" requested by " in bot_status.description)
and not build_only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iarspider , may be this is also not needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

):
signatures["tests"] = "started"
if (
Expand All @@ -2136,17 +2155,17 @@ def process_pr(
for status in commit_statuses:
if not status.context.startswith(cms_status_prefix + "/"):
continue
cdata = status.context.split("/")
if cdata[-1] not in ["optional", "required"]:
scontext, suffix = status.context.rsplit("/", 1)
if suffix not in ["optional", "required"]:
continue
if (cdata[-1] not in lab_stats) or (cdata[-1] == "required"):
lab_stats[cdata[-1]] = []
lab_stats[cdata[-1]].append("pending")
if (suffix not in lab_stats) or (suffix == "required"):
lab_stats[suffix] = []
lab_stats[suffix].append("pending")
if status.state == "pending":
continue
scontext = "/".join(cdata[:-1])
all_states = {}
result_url = ""
build_only_flag = False
for s in [
i
for i in commit_statuses
Expand All @@ -2163,7 +2182,18 @@ def process_pr(
if s.state not in all_states:
all_states[s.state] = []
all_states[s.state].append(s.context)
if s.context.endswith("/build_only") and s.description == "Only build":
build_only_flag = True
break

logger.debug("Test status for %s: %s", status.context, all_states)
if build_only_flag:
logger.debug("Skipping build-only context %s", scontext)
# Undo changes to lab_stats
lab_stats[suffix].pop()
if not lab_stats[suffix]:
del lab_stats[suffix]
continue
if "pending" in all_states:
if status.description.startswith("Finished"):
logger.info(
Expand All @@ -2179,18 +2209,18 @@ def process_pr(
)
continue
if "success" in all_states:
lab_stats[cdata[-1]][-1] = "success"
lab_stats[suffix][-1] = "success"
if "error" in all_states:
if [c for c in all_states["error"] if ("/opt/" not in c)]:
lab_stats[cdata[-1]][-1] = "error"
lab_stats[suffix][-1] = "error"
logger.info(
"Final Status: status.context=%s cdata[-1]=%s lab_stats[cdata[-1]][-1]=%s status.description=%s",
"Final Status: status.context=%s suffix=%s lab_stats[suffix][-1]=%s status.description=%s",
status.context,
cdata[-1],
lab_stats[cdata[-1]][-1],
suffix,
lab_stats[suffix][-1],
status.description,
)
if (lab_stats[cdata[-1]][-1] != "pending") and (
if (lab_stats[suffix][-1] != "pending") and (
not status.description.startswith("Finished")
):
if result_url:
Expand All @@ -2208,7 +2238,7 @@ def process_pr(
raise Exception("System-error: unable to get PR result")
if o and (not dryRun):
res = "+1"
if lab_stats[cdata[-1]][-1] == "error":
if lab_stats[suffix][-1] == "error":
res = "-1"
res = "%s\n\n%s" % (res, o)
issue.create_comment(res)
Expand Down Expand Up @@ -2355,7 +2385,7 @@ def process_pr(
labels.append("requires-external")

# Keep old tests state for closed PRs (workaround for missing commit statuses in old PRs)
if not create_status:
if not create_status or build_only:
labels = [l for l in labels if not l.startswith("tests-")]
labels.extend(l for l in old_labels if l.startswith("tests-"))

Expand Down Expand Up @@ -2470,6 +2500,7 @@ def process_pr(
global_test_params["EXTRA_RELVALS_TESTS"] = " ".join(
[t.upper().replace("-", "_") for t in EXTRA_RELVALS_TESTS]
)
global_test_params["BUILD_ONLY"] = build_only

logger.debug("All Parameters: %s", global_test_params)
# For now, only trigger tests for cms-sw/cmssw and cms-sw/cmsdist
Expand Down
3 changes: 2 additions & 1 deletion tests/PRActionData/TestProcessPr.test_abort.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@
"PULL_REQUESTS": "iarspider-cmssw/cmssw#17 cms-sw/cms-bot#2134",
"RELEASE_FORMAT": "CMSSW_14_1_CPP20_X",
"EXTRA_RELVALS_TESTS": "THREADING GPU HIGH_STATS NANO CUDA ROCM",
"CONTEXT_PREFIX": "cms/17"
"CONTEXT_PREFIX": "cms/17",
"BUILD_ONLY": false
}
}
},
Expand Down
50 changes: 50 additions & 0 deletions tests/PRActionData/TestProcessPr.test_build_only.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
{
"type": "load-bot-cache",
"data": {
"commits": {
"06336c8884bcfbc516cc69fd99b0a161bb3a14d5": {
"files": [
"RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalUncalibRecHitPhase2WeightsAlgoPortable.dev.cc"
],
"squashed": false,
"time": 1747049040
}
},
"emoji": {},
"last_seen_sha": "06336c8884bcfbc516cc69fd99b0a161bb3a14d5",
"signatures": {}
}
},
{
"type": "add-label",
"data": []
},
{
"type": "remove-label",
"data": []
},
{
"type": "edit-comment",
"data": "cms-bot internal usage<!-- bot cache: {\"commits\":{\"06336c8884bcfbc516cc69fd99b0a161bb3a14d5\":{\"files\":[\"RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalUncalibRecHitPhase2WeightsAlgoPortable.dev.cc\"],\"squashed\":false,\"time\":1747049040}},\"emoji\":{\"2872583904\":\"+1\"},\"last_seen_sha\":\"06336c8884bcfbc516cc69fd99b0a161bb3a14d5\",\"signatures\":{}} -->"
},
{
"type": "save-bot-cache",
"data": {
"commits": {
"06336c8884bcfbc516cc69fd99b0a161bb3a14d5": {
"files": [
"RecoLocalCalo/EcalRecProducers/plugins/alpaka/EcalUncalibRecHitPhase2WeightsAlgoPortable.dev.cc"
],
"squashed": false,
"time": 1747049040
}
},
"emoji": {
"2872583904": "+1"
},
"last_seen_sha": "06336c8884bcfbc516cc69fd99b0a161bb3a14d5",
"signatures": {}
}
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
"data": {
"PULL_REQUESTS": "iarspider-cmssw/cmsdist#1",
"EXTRA_RELVALS_TESTS": "THREADING GPU HIGH_STATS NANO CUDA ROCM",
"CONTEXT_PREFIX": "cms/1"
"CONTEXT_PREFIX": "cms/1",
"BUILD_ONLY": false
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion tests/PRActionData/TestProcessPr.test_draft_pr_ready.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
"data": {
"PULL_REQUESTS": "iarspider-cmssw/cmssw#21",
"EXTRA_RELVALS_TESTS": "THREADING GPU HIGH_STATS NANO CUDA ROCM",
"CONTEXT_PREFIX": "cms/21"
"CONTEXT_PREFIX": "cms/21",
"BUILD_ONLY": false
}
}
},
Expand Down
Loading