Skip to content

Commit

Permalink
Fix lint and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
driazati committed Jan 14, 2022
1 parent be555cd commit f87c1a0
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ready_for_merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eux
python check_pr_is_ready.py --sha "$SHA"
python tests/scripts/github_check_pr_is_mergeable.py --sha "$SHA"
76 changes: 76 additions & 0 deletions tests/python/unittest/test_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,89 @@
import pathlib
import subprocess
import sys
import json
import tempfile

import pytest

REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent.parent.parent


def test_pr_is_mergable():
is_mergable_script = REPO_ROOT / "tests" / "scripts" / "github_check_pr_is_mergeable.py"

def run(decision, statuses, mergeable):
# Mock out the response from GitHub's API
data = {
"reviewDecision": decision,
"commits": {
"nodes": [{"commit": {"statusCheckRollup": {"contexts": {"nodes": statuses}}}}]
},
}
proc = subprocess.run(
[str(is_mergable_script), "--pr-json", json.dumps(data)],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="utf-8",
)
if proc.returncode != 0:
raise RuntimeError(f"Process failed:\nstdout:\n{proc.stdout}\n\nstderr:\n{proc.stderr}")

# Find the relevant string in the output
if mergeable:
assert "PR passed CI and is approved, labelling" in proc.stdout
else:
assert "PR is not ready for merge" in proc.stdout

# mergeable should be true iff all statuses are successful and PR is approved
run(decision="CHANGES_REQUESTED", statuses=[], mergeable=False)
run(decision="APPROVED", statuses=[], mergeable=True)
run(
decision="CHANGES_REQUESTED",
statuses=[
{
"context": "abc",
"state": "FAILED",
}
],
mergeable=False,
)
run(
decision="APPROVED",
statuses=[
{
"context": "abc",
"state": "FAILED",
}
],
mergeable=False,
)
run(
decision="APPROVED",
statuses=[
{
"context": "abc",
"state": "SUCCESS",
}
],
mergeable=True,
)
run(
decision="APPROVED",
statuses=[
{
"context": "abc",
"state": "SUCCESS",
},
{
"context": "abc2",
"state": "FAILURE",
},
],
mergeable=False,
)


def test_skip_ci():
skip_ci_script = REPO_ROOT / "tests" / "scripts" / "git_skip_ci.py"

Expand Down
2 changes: 1 addition & 1 deletion tests/scripts/git_skip_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import os
import argparse

from .git_utils import git, GitHubRepo, parse_remote
from git_utils import git, GitHubRepo, parse_remote


if __name__ == "__main__":
Expand Down
18 changes: 18 additions & 0 deletions tests/scripts/git_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
#!/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 json
import subprocess
import re
Expand Down
36 changes: 25 additions & 11 deletions tests/scripts/github_check_pr_is_mergeable.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from urllib import error
from typing import Dict, Tuple, Any

from .git_utils import git, GitHubRepo, parse_remote
from git_utils import git, GitHubRepo, parse_remote


def commit_query(repo: str, user: str, sha: str) -> str:
Expand Down Expand Up @@ -102,25 +102,39 @@ def is_pr_ready(data: Any) -> bool:
if __name__ == "__main__":
help = "Adds label to PRs that have passed CI and are approved"
parser = argparse.ArgumentParser(description=help)
parser.add_argument("--sha", required=True)
parser.add_argument("--sha")
parser.add_argument("--remote", default="origin", help="ssh remote to parse")
parser.add_argument("--label", default="ready-for-merge", help="label to add")
parser.add_argument(
"--pr-json", help="(testing) PR data to use instead of fetching from GitHub"
)
args = parser.parse_args()

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)

data = github.graphql(commit_query(repo, user, args.sha))
pr = data["data"]["repository"]["object"]["associatedPullRequests"]["nodes"][0]
is_testing = args.pr_json is not None
if not is_testing and args.sha is None:
print("--sha must be used outside of testing")
exit(1)

if args.pr_json:
pr = json.loads(args.pr_json)
else:
github = GitHubRepo(token=os.environ["GITHUB_TOKEN"], user=user, repo=repo)

data = github.graphql(commit_query(repo, user, args.sha))
pr = data["data"]["repository"]["object"]["associatedPullRequests"]["nodes"][0]

if is_pr_ready(pr):
print("PR passed CI and is approved, labelling...")
github.post(f"issues/{pr['number']}/labels", {"labels": [args.label]})
if not is_testing:
github.post(f"issues/{pr['number']}/labels", {"labels": [args.label]})
else:
print("PR is not ready for merge")
try:
github.delete(f"issues/{pr['number']}/labels/{args.label}")
except error.HTTPError as e:
print(e)
print("Failed to remove label (it may not have been there at all)")
if not is_testing:
try:
github.delete(f"issues/{pr['number']}/labels/{args.label}")
except error.HTTPError as e:
print(e)
print("Failed to remove label (it may not have been there at all)")

0 comments on commit f87c1a0

Please sign in to comment.