Skip to content

Commit

Permalink
[skip ci][ci] Fix Jenkinsfile (apache#12387)
Browse files Browse the repository at this point in the history
This got out of date after merging apache#12178

Co-authored-by: driazati <driazati@users.noreply.github.com>
  • Loading branch information
driazati and driazati committed Aug 11, 2022
1 parent de12486 commit 2cf9376
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 4 deletions.
23 changes: 21 additions & 2 deletions Jenkinsfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion ci/jenkins/Prepare.groovy.j2
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def should_skip_ci(pr_number) {
}
withCredentials([string(
credentialsId: 'tvm-bot-jenkins-reader',
variable: 'TOKEN',
variable: 'GITHUB_TOKEN',
)]) {
// Exit code of 1 means run full CI (or the script had an error, so run
// full CI just in case). Exit code of 0 means skip CI.
Expand All @@ -126,12 +126,31 @@ def should_skip_ci(pr_number) {
return git_skip_ci_code == 0
}

def check_pr(pr_number) {
if (env.BRANCH_NAME == null || !env.BRANCH_NAME.startsWith('PR-')) {
// never skip CI on build sourced from a branch
return false
}
withCredentials([string(
credentialsId: 'tvm-bot-jenkins-reader',
variable: 'GITHUB_TOKEN',
)]) {
sh (
script: "python3 tests/scripts/check_pr.py --pr ${pr_number}",
label: 'Check PR title and body',
)
}

}

def prepare() {
stage('Prepare') {
node('CPU-SMALL') {
ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/prepare") {
init_git()

check_pr(env.CHANGE_ID)

if (env.DETERMINE_DOCKER_IMAGES == 'yes') {
sh(
script: "./tests/scripts/determine_docker_images.py {% for image in images %}{{ image.name }}={% raw %}${{% endraw %}{{ image.name }}{% raw %}}{% endraw %} {% endfor %}",
Expand Down
151 changes: 151 additions & 0 deletions tests/scripts/check_pr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# 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.
import argparse
import re
import os
import textwrap
from dataclasses import dataclass
from typing import Any, List, Callable


from git_utils import GitHubRepo, parse_remote, git
from cmd_utils import init_log, tags_from_title


GITHUB_USERNAME_REGEX = re.compile(r"(@[a-zA-Z0-9-]+)", flags=re.MULTILINE)
OK = object()


@dataclass
class Check:
# check to run, returning OK means it passed, anything else means it failed
check: Callable[[str], Any]

# function to call to generate the error message
error_fn: Callable[[Any], str]


def non_empty(s: str):
if len(s) == 0:
return False
return OK


def usernames(s: str):
m = GITHUB_USERNAME_REGEX.findall(s)
if m and len(m) > 0:
return m
return OK


def tags(s: str):
items = tags_from_title(s)
if len(items) == 0:
return False
return OK


def trailing_period(s: str):
if s.endswith("."):
return False
return OK


title_checks = [
Check(check=non_empty, error_fn=lambda d: "PR must have a title but title was empty"),
Check(check=trailing_period, error_fn=lambda d: "PR must not end in a tailing '.'"),
Check(
check=usernames,
error_fn=lambda d: f"PR title must not tag anyone but found these usernames: {d}",
),
Check(
check=tags,
error_fn=lambda d: f"PR title must have a topic tag like [the_topic] (e.g. [tir], [relay], etc.) but found none",
),
]
body_checks = [
Check(check=non_empty, error_fn=lambda d: "PR must have a body but body was empty"),
Check(
check=usernames,
error_fn=lambda d: f"PR body must not tag anyone but found these usernames: {d}",
),
]


def run_checks(checks: List[Check], s: str, name: str) -> bool:
errors = [(c, c.check(s)) for c in checks]
errors = [item for item in errors if item[1] != OK]
errors = []
print(f"Running checks for {name}")
print(textwrap.indent(s, prefix=" "))
passed = True
print(" Checks:")
for i, check in enumerate(checks):
result = check.check(s)
if result == OK:
print(f" [{i+1}] {check.check.__name__}: PASSED")
else:
passed = False
msg = check.error_fn(result)
print(f" [{i+1}] {check.check.__name__}: FAILED: {msg}")

return passed


if __name__ == "__main__":
init_log()
help = "Check a PR's title and body for conformance to guidelines"
parser = argparse.ArgumentParser(description=help)
parser.add_argument("--pr", required=True)
parser.add_argument("--remote", default="origin", help="ssh remote to parse")
parser.add_argument(
"--pr-body", help="(testing) PR body to use instead of fetching from GitHub"
)
parser.add_argument(
"--pr-title", help="(testing) PR title to use instead of fetching from GitHub"
)
args = parser.parse_args()

try:
pr = int(args.pr)
except ValueError:
print(f"PR was not a number: {args.pr}")
exit(0)

if args.pr_body:
body = args.pr_body
title = args.pr_title
else:
remote = git(["config", "--get", f"remote.{args.remote}.url"])
user, repo = parse_remote(remote)

github = GitHubRepo(token=os.environ["GITHUB_TOKEN"], user=user, repo=repo)
pr = github.get(f"pulls/{args.pr}")
body = pr["body"]
title = pr["title"]

title_passed = run_checks(checks=title_checks, s=title, name="PR title")
print("")
body_passed = run_checks(checks=body_checks, s=body, name="PR body")

if title_passed and body_passed:
print("All checks passed!")
exit(0)
else:
print("Some checks failed, please review the logs above")
exit(1)
2 changes: 1 addition & 1 deletion tests/scripts/git_skip_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def check_pr_title():
if args.pr_title:
title = args.pr_title
else:
github = GitHubRepo(token=os.environ["TOKEN"], user=user, repo=repo)
github = GitHubRepo(token=os.environ["GITHUB_TOKEN"], user=user, repo=repo)
pr = github.get(f"pulls/{args.pr}")
title = pr["title"]
logging.info(f"pr title: {title}")
Expand Down

0 comments on commit 2cf9376

Please sign in to comment.