Exemple #1
0
def test_jinja_with_list_attribute():
    pull_request_rules = rules.UserConfigurationSchema("""
        pull_request_rules:
          - name: ahah
            conditions:
            - base=master
            actions:
              comment:
                message: |
                  This pull request has been approved by:
                  {% for name in label %}
                  @{{name}}
                  {% endfor %}
                  {% for name in files %}
                  @{{name}}
                  {% endfor %}
                  {% for name in assignee %}
                  @{{name}}
                  {% endfor %}
                  {% for name in approved_reviews_by %}
                  @{{name}}
                  {% endfor %}
                  Thank you @{{author}} for your contributions!
        """)["pull_request_rules"]
    assert [rule.name for rule in pull_request_rules] == [
        "ahah",
    ]
Exemple #2
0
def test_jinja_with_wrong_syntax():
    with pytest.raises(voluptuous.Invalid) as i:
        rules.UserConfigurationSchema(
            rules.YamlSchema(
                """pull_request_rules:
  - name: ahah
    conditions:
    - base=master
    actions:
      comment:
        message: |
          This pull request has been approved by:
          {% for name in approved_reviews_by %}
          Thank you @{{author}} for your contributions!
"""
            )
        )
    assert str(i.value) == (
        "Template syntax error @ data['pull_request_rules']"
        "[0]['actions']['comment']['message'][line 3]"
    )

    with pytest.raises(voluptuous.Invalid) as i:
        rules.UserConfigurationSchema(
            rules.YamlSchema(
                """pull_request_rules:
  - name: ahah
    conditions:
    - base=master
    actions:
      comment:
        message: |
          This pull request has been approved by:
          {% for name in approved_reviews_by %}
          @{{ name }}
          {% endfor %}
          Thank you @{{foo}} for your contributions!
"""
            )
        )
    assert str(i.value) == (
        "Template syntax error for dictionary value @ data['pull_request_rules']"
        "[0]['actions']['comment']['message']"
    )
Exemple #3
0
def test_user_binary_file():
    with pytest.raises(voluptuous.Invalid) as i:
        rules.UserConfigurationSchema(chr(4))
    assert str(i.value) == "Invalid YAML at []"
    ir = rules.InvalidRules(i.value, ".mergify.yml")
    assert (str(ir) == """Invalid YAML
```
unacceptable character #x0004: special characters are not allowed
  in "<unicode string>", position 0
```""")
    assert ir.get_annotations(".mergify.yml") == []
Exemple #4
0
def config_validator():  # pragma: no cover
    try:
        rules.UserConfigurationSchema(flask.request.files["data"].stream)
    except Exception as e:
        status = 400
        message = str(e)
    else:
        status = 200
        message = "The configuration is valid"

    return flask.Response(message, status=status, mimetype="text/plain")
Exemple #5
0
def test_user_configuration_schema():
    with pytest.raises(voluptuous.Invalid) as exc_info:
        rules.UserConfigurationSchema("- no\n* way")
    assert exc_info.value.__class__.__name__, "YamlInvalid"
    assert str(exc_info.value.path) == "[at position 2:2]"
    assert exc_info.value.path == [{"line": 2, "column": 2}]

    with pytest.raises(voluptuous.Invalid):
        rules.UserConfigurationSchema("""
pull_request_rules:
  - name: ahah
    key: not really what we expected
""")

    with pytest.raises(voluptuous.Invalid):
        rules.UserConfigurationSchema("""
pull_request_rules:
""")

    with pytest.raises(voluptuous.Invalid):
        rules.UserConfigurationSchema("")
Exemple #6
0
def test_check_runs_default():
    pull_request_rules = rules.UserConfigurationSchema("""
pull_request_rules:
  - name: ahah
    conditions:
    - base=master
    actions:
      post_check: {}
""")["pull_request_rules"]
    assert [rule.name for rule in pull_request_rules] == [
        "ahah",
    ]
async def config_validator(
        data: fastapi.UploadFile = fastapi.File(...), ):  # pragma: no cover
    try:
        rules.UserConfigurationSchema(await data.read())
    except Exception as e:
        status = 400
        message = str(e)
    else:
        status = 200
        message = "The configuration is valid"

    return responses.PlainTextResponse(message, status_code=status)
Exemple #8
0
def test_check_runs_custom():
    pull_request_rules = rules.UserConfigurationSchema("""
pull_request_rules:
  - name: ahah
    conditions:
    - base=master
    actions:
      post_check:
        title: '{{ check_rule_name }} whatever'
        summary: |
          This pull request has been checked!
          Thank you @{{author}} for your contributions!

          {{ check_conditions }}

""")["pull_request_rules"]
    assert [rule.name for rule in pull_request_rules] == [
        "ahah",
    ]
Exemple #9
0
LOG = daiquiri.getLogger(__name__)

MERGIFY_BUILTIN_CONFIG_YAML = f"""
pull_request_rules:
  - name: delete backport/copy branch (Mergify rule)
    hidden: true
    conditions:
      - author={config.BOT_USER_LOGIN}
      - head~=^mergify/(bp|copy)/
      - closed
    actions:
        delete_head_branch:
"""

MERGIFY_BUILTIN_CONFIG = rules.UserConfigurationSchema(
    rules.YamlSchema(MERGIFY_BUILTIN_CONFIG_YAML))

DEFAULT_CONFIG_FILE = context.MergifyConfigFile(
    decoded_content=b"",
    type="file",
    content="<default>",
    sha=github_types.SHAType("<default>"),
    path="<default>",
)


async def _check_configuration_changes(
    ctxt: context.Context,
    current_mergify_config_file: typing.Optional[context.MergifyConfigFile],
) -> bool:
    if ctxt.pull["base"]["repo"]["default_branch"] != ctxt.pull["base"]["ref"]:
Exemple #10
0
def report(url):
    redis = utils.get_redis_for_cache()
    path = url.replace("https://github.com/", "")
    try:
        owner, repo, _, pull_number = path.split("/")
    except ValueError:
        print(f"Wrong URL: {url}")
        return
    slug = owner + "/" + repo

    integration = github.GithubIntegration(config.INTEGRATION_ID,
                                           config.PRIVATE_KEY)
    install_id = utils.get_installation_id(integration, owner, repo=repo)

    print("* INSTALLATION ID: %s" % install_id)

    cached_sub = sub_utils.get_subscription(redis, install_id)
    db_sub = sub_utils._retrieve_subscription_from_db(install_id)
    print("* SUBSCRIBED (cache/db): %s / %s" %
          (cached_sub["subscription_active"], db_sub["subscription_active"]))
    report_sub(install_id, slug, cached_sub, "ENGINE-CACHE")
    report_sub(install_id, slug, db_sub, "DASHBOARD")

    installation_token = integration.get_access_token(install_id).token

    g = github.Github(installation_token,
                      base_url="https://api.%s" % config.GITHUB_DOMAIN)
    r = g.get_repo(owner + "/" + repo)
    print("* REPOSITORY IS %s" % "PRIVATE" if r.private else "PUBLIC")

    print("* CONFIGURATION:")
    try:
        mergify_config_content = rules.get_mergify_config_content(r)
    except rules.NoRules:  # pragma: no cover
        print(".mergify.yml is missing")
    else:
        print(mergify_config_content.decode())

    try:
        mergify_config = rules.UserConfigurationSchema(mergify_config_content)
    except rules.InvalidRules as e:  # pragma: no cover
        print("configuration is invalid %s" % str(e))
    else:
        pull_request_rules_raw = mergify_config["pull_request_rules"].as_dict()
        pull_request_rules_raw["rules"].extend(
            actions_runner.MERGIFY_RULE["rules"])
        pull_request_rules = rules.PullRequestRules(**pull_request_rules_raw)

    try:
        p = r.get_pull(int(pull_number))
    except github.UnknownObjectException:
        print("Wrong pull request number")
        return g, None

    mp = mergify_pull.MergifyPull(g, p, install_id)
    print("* PULL REQUEST:")
    pprint.pprint(mp.to_dict(), width=160)
    try:
        print("is_behind: %s" % mp.is_behind())
    except github.GithubException as e:
        print("Unable to know if pull request branch is behind: %s" % e)

    print("mergeable_state: %s" % mp.g_pull.mergeable_state)

    print("* MERGIFY LAST CHECKS:")
    checks = list(check_api.get_checks(p))
    for c in checks:
        if c._rawData["app"]["id"] == config.INTEGRATION_ID:
            print("[%s]: %s | %s" %
                  (c.name, c.conclusion, c.output.get("title")))
            print("> " + "\n> ".join(c.output.get("summary").split("\n")))

    print("* MERGIFY LIVE MATCHES:")
    match = pull_request_rules.get_pull_request_rule(mp)
    summary_title, summary = actions_runner.gen_summary(
        "refresh", {}, mp, match)
    print("> %s" % summary_title)
    print(summary)

    return g, p
Exemple #11
0
def report(url):
    redis = utils.get_redis_for_cache()
    path = url.replace("https://github.com/", "")
    try:
        owner, repo, _, pull_number = path.split("/")
    except ValueError:
        print(f"Wrong URL: {url}")
        return
    slug = owner + "/" + repo

    try:
        installation = github.get_installation(owner, repo)
    except exceptions.MergifyNotInstalled:
        print("* Mergify is not installed there")
        return

    client = github.get_client(owner, repo, installation)

    print("* INSTALLATION ID: %s" % client.installation["id"])

    cached_sub = sub_utils.get_subscription(redis, client.installation["id"])
    db_sub = sub_utils._retrieve_subscription_from_db(
        client.installation["id"])
    print("* SUBSCRIBED (cache/db): %s / %s" %
          (cached_sub["subscription_active"], db_sub["subscription_active"]))
    report_sub(client.installation["id"], slug, cached_sub, "ENGINE-CACHE")
    report_sub(client.installation["id"], slug, db_sub, "DASHBOARD")

    pull_raw = client.item(f"pulls/{pull_number}")
    ctxt = mergify_context.MergifyContext(client, pull_raw)

    print("* REPOSITORY IS %s" %
          "PRIVATE" if ctxt.pull["base"]["repo"]["private"] else "PUBLIC")

    print("* CONFIGURATION:")
    try:
        mergify_config_content = rules.get_mergify_config_content(ctxt)
    except rules.NoRules:  # pragma: no cover
        print(".mergify.yml is missing")
        pull_request_rules = None
    else:
        print(mergify_config_content.decode())
        try:
            mergify_config = rules.UserConfigurationSchema(
                mergify_config_content)
        except rules.InvalidRules as e:  # pragma: no cover
            print("configuration is invalid %s" % str(e))
        else:
            pull_request_rules_raw = mergify_config[
                "pull_request_rules"].as_dict()
            pull_request_rules_raw["rules"].extend(
                engine.MERGIFY_RULE["rules"])
            pull_request_rules = rules.PullRequestRules(
                **pull_request_rules_raw)

    print("* PULL REQUEST:")
    pprint.pprint(ctxt.to_dict(), width=160)

    print("is_behind: %s" % ctxt.is_behind)

    print("mergeable_state: %s" % ctxt.pull["mergeable_state"])

    print("* MERGIFY LAST CHECKS:")
    checks = list(check_api.get_checks(ctxt, mergify_only=True))
    for c in checks:
        print("[%s]: %s | %s" %
              (c["name"], c["conclusion"], c["output"].get("title")))
        print("> " + "\n> ".join(c["output"].get("summary").split("\n")))

    if pull_request_rules is not None:
        print("* MERGIFY LIVE MATCHES:")
        match = pull_request_rules.get_pull_request_rule(ctxt)
        summary_title, summary = actions_runner.gen_summary(
            ctxt, [{
                "event_type": "refresh",
                "data": {}
            }], match)
        print("> %s" % summary_title)
        print(summary)

    return ctxt
Exemple #12
0
def report(
    url: str,
) -> typing.Union[context.Context, github.GithubInstallationClient, None]:
    path = url.replace("https://github.com/", "")

    pull_number: typing.Optional[str]
    repo: typing.Optional[str]

    try:
        owner, repo, _, pull_number = path.split("/")
    except ValueError:
        pull_number = None
        try:
            owner, repo = path.split("/")
        except ValueError:
            owner = path
            repo = None

    try:
        client = github.get_client(owner)
    except exceptions.MergifyNotInstalled:
        print(f"* Mergify is not installed on account {owner}")
        return None

    print("* INSTALLATION ID: %s" % client.auth.installation["id"])

    cached_sub, db_sub = utils.async_run(
        subscription.Subscription.get_subscription(client.auth.owner_id),
        subscription.Subscription._retrieve_subscription_from_db(
            client.auth.owner_id),
    )

    if repo is None:
        slug = None
    else:
        slug = owner + "/" + repo

    print("* SUBSCRIBED (cache/db): %s / %s" %
          (cached_sub.active, db_sub.active))
    print("* Features (cache):")
    for f in cached_sub.features:
        print(f"  - {f.value}")
    report_sub(client.auth.installation["id"], cached_sub, "ENGINE-CACHE",
               slug)
    report_sub(client.auth.installation["id"], db_sub, "DASHBOARD", slug)

    utils.async_run(report_worker_status(client.auth.owner))

    if repo is not None:

        repo_info = client.item(f"/repos/{owner}/{repo}")
        print(
            f"* REPOSITORY IS {'PRIVATE' if repo_info['private'] else 'PUBLIC'}"
        )

        print("* CONFIGURATION:")
        mergify_config = None
        try:
            filename, mergify_config_content = rules.get_mergify_config_content(
                client, repo)
        except rules.NoRules:  # pragma: no cover
            print(".mergify.yml is missing")
        else:
            print(f"Config filename: {filename}")
            print(mergify_config_content.decode())
            try:
                mergify_config = rules.UserConfigurationSchema(
                    mergify_config_content)
            except rules.InvalidRules as e:  # pragma: no cover
                print("configuration is invalid %s" % str(e))
            else:
                mergify_config["pull_request_rules"].rules.extend(
                    engine.DEFAULT_PULL_REQUEST_RULES.rules)

        if pull_number is None:
            for branch in client.items(f"/repos/{owner}/{repo}/branches"):
                q = queue.Queue(
                    utils.get_redis_for_cache(),
                    client.auth.installation["id"],
                    client.auth.owner,
                    repo,
                    branch["name"],
                )
                pulls = q.get_pulls()
                if not pulls:
                    continue

                print(f"* QUEUES {branch['name']}:")

                for priority, grouped_pulls in itertools.groupby(
                        pulls, key=lambda v: q.get_config(v)["priority"]):
                    try:
                        fancy_priority = helpers.PriorityAliases(priority).name
                    except ValueError:
                        fancy_priority = priority
                    formatted_pulls = ", ".join(
                        (f"#{p}" for p in grouped_pulls))
                    print(f"** {formatted_pulls} (priority: {fancy_priority})")
        else:
            pull_raw = client.item(
                f"/repos/{owner}/{repo}/pulls/{pull_number}")
            ctxt = context.Context(
                client,
                pull_raw,
                cached_sub,
                [{
                    "event_type": "mergify-debugger",
                    "data": {}
                }],
            )

            # FIXME queues could also be printed if no pull number given
            q = queue.Queue.from_context(ctxt)
            print("* QUEUES: %s" % ", ".join([f"#{p}" for p in q.get_pulls()]))
            print("* PULL REQUEST:")
            pr_data = dict(ctxt.pull_request.items())
            pprint.pprint(pr_data, width=160)

            print("is_behind: %s" % ctxt.is_behind)

            print("mergeable_state: %s" % ctxt.pull["mergeable_state"])

            print("* MERGIFY LAST CHECKS:")
            for c in ctxt.pull_engine_check_runs:
                print("[%s]: %s | %s" %
                      (c["name"], c["conclusion"], c["output"].get("title")))
                print("> " +
                      "\n> ".join(c["output"].get("summary").split("\n")))

            if mergify_config is not None:
                print("* MERGIFY LIVE MATCHES:")
                match = mergify_config[
                    "pull_request_rules"].get_pull_request_rule(ctxt)
                summary_title, summary = actions_runner.gen_summary(
                    ctxt, match)
                print("> %s" % summary_title)
                print(summary)

            return ctxt

    return client
Exemple #13
0
def test_user_configuration_schema():
    with pytest.raises(voluptuous.Invalid) as exc_info:
        rules.UserConfigurationSchema("- no\n* way")
    assert str(exc_info.value) == "Invalid YAML at [line 2, column 2]"

    with pytest.raises(voluptuous.Invalid) as i:
        rules.UserConfigurationSchema("""
            pull_request_rules:
              - name: ahah
                key: not really what we expected
            """)
    assert (str(i.value) ==
            "extra keys not allowed @ data['pull_request_rules'][0]['key']")

    ir = rules.InvalidRules(i.value, ".mergify.yml")
    assert str(ir) == (
        "* extra keys not allowed @ pull_request_rules → item 0 → key\n"
        "* required key not provided @ pull_request_rules → item 0 → actions\n"
        "* required key not provided @ pull_request_rules → item 0 → conditions"
    )
    assert [] == ir.get_annotations(".mergify.yml")

    with pytest.raises(voluptuous.Invalid) as i:
        rules.UserConfigurationSchema("""invalid:
- *yaml
""")
    assert str(i.value) == "Invalid YAML at [line 2, column 3]"

    ir = rules.InvalidRules(i.value, ".mergify.yml")
    assert (str(ir) == """Invalid YAML @ line 2, column 3
```
found undefined alias 'yaml'
  in "<unicode string>", line 2, column 3:
    - *yaml
      ^
```""")
    assert [{
        "annotation_level":
        "failure",
        "end_column":
        3,
        "end_line":
        2,
        "message":
        "found undefined alias 'yaml'\n"
        '  in "<unicode string>", line 2, column 3:\n'
        "    - *yaml\n"
        "      ^",
        "path":
        ".mergify.yml",
        "start_column":
        3,
        "start_line":
        2,
        "title":
        "Invalid YAML",
    }] == ir.get_annotations(".mergify.yml")

    with pytest.raises(voluptuous.Invalid) as i:
        rules.UserConfigurationSchema("""
pull_request_rules:
""")
    assert (str(
        i.value
    ) == "expected a list for dictionary value @ data['pull_request_rules']")
    ir = rules.InvalidRules(i.value, ".mergify.yml")
    assert str(
        ir) == "expected a list for dictionary value @ pull_request_rules"

    with pytest.raises(voluptuous.Invalid) as i:
        rules.UserConfigurationSchema("")
    assert str(i.value) == "expected a dictionary"
    ir = rules.InvalidRules(i.value, ".mergify.yml")
    assert str(ir) == "expected a dictionary"

    with pytest.raises(voluptuous.Invalid) as i:
        rules.UserConfigurationSchema("""
            pull_request_rules:
              - name: add label
                conditions:
                  - conflict
                actions:
                  label:
                    add:
                      - conflict:
            """)
    assert (
        str(i.value) ==
        "expected str @ data['pull_request_rules'][0]['actions']['label']['add'][0]"
    )
    ir = rules.InvalidRules(i.value, ".mergify.yml")
    assert (
        str(ir) ==
        "expected str @ pull_request_rules → item 0 → actions → label → add → item 0"
    )
Exemple #14
0
def report(url):
    redis = utils.get_redis_for_cache()
    path = url.replace("https://github.com/", "")
    owner, repo, _, pull_number = path.split("/")

    integration = github.GithubIntegration(config.INTEGRATION_ID,
                                           config.PRIVATE_KEY)
    install_id = utils.get_installation_id(integration, owner, repo=repo)

    print("* INSTALLATION ID: %s" % install_id)

    cached_sub = sub_utils.get_subscription(redis, install_id)
    db_sub = sub_utils._retrieve_subscription_from_db(install_id)
    print("* SUBSCRIBED (cache/db): %s / %s" %
          (cached_sub["subscription_active"], db_sub["subscription_active"]))
    print("* SUB DETAIL: %s" % db_sub["subscription_reason"])

    print("* NUMBER OF CACHED TOKENS: %d" % len(cached_sub["tokens"]))

    try:
        for login, token in cached_sub["tokens"].items():
            try:
                repos = get_repositories_setuped(token, install_id)
            except github.BadCredentialsException:
                print("** token for %s invalid" % login)
            except github.GithubException as e:
                if e.status != 401:
                    raise
                print("** token for %s invalid" % login)
            else:
                if any((r["full_name"] == owner + "/" + repo) for r in repos):
                    print("* MERGIFY INSTALLED AND ENABLED ON THIS REPOSITORY")
                else:
                    print("* MERGIFY INSTALLED BUT DISABLED "
                          "ON THIS REPOSITORY")
                break
        else:
            print("* MERGIFY DOESN'T HAVE ANY VALID OAUTH TOKENS")
    except github.UnknownObjectException:
        print("* MERGIFY SEEMS NOT INSTALLED")

    installation_token = integration.get_access_token(install_id).token

    g = github.Github(installation_token,
                      base_url="https://api.%s" % config.GITHUB_DOMAIN)
    r = g.get_repo(owner + "/" + repo)
    print("* REPOSITORY IS %s" % "PRIVATE" if r.private else "PUBLIC")

    print("* CONFIGURATION:")
    try:
        mergify_config_content = rules.get_mergify_config_content(r)
    except rules.NoRules:  # pragma: no cover
        print(".mergify.yml is missing")

    print(mergify_config_content.decode())

    try:
        mergify_config = rules.UserConfigurationSchema(mergify_config_content)
    except rules.InvalidRules as e:  # pragma: no cover
        print("configuration is invalid %s" % str(e))
    else:
        pull_request_rules_raw = mergify_config["pull_request_rules"].as_dict()
        pull_request_rules_raw["rules"].extend(
            actions_runner.MERGIFY_RULE["rules"])
        pull_request_rules = rules.PullRequestRules(**pull_request_rules_raw)

    try:
        p = r.get_pull(int(pull_number))
    except github.UnknownObjectException:
        print("Wrong pull request number")
        return g, None

    mp = mergify_pull.MergifyPull(g, p, install_id)
    print("* PULL REQUEST:")
    pprint.pprint(mp.to_dict(), width=160)
    try:
        print("is_behind: %s" % mp.is_behind())
    except github.GithubException as e:
        print("Unable to know if pull request branch is behind: %s" % e)

    print("mergeable_state: %s" % mp.g_pull.mergeable_state)

    print("* MERGIFY LAST CHECKS:")
    checks = list(check_api.get_checks(p))
    for c in checks:
        if c._rawData["app"]["id"] == config.INTEGRATION_ID:
            print("[%s]: %s | %s" %
                  (c.name, c.conclusion, c.output.get("title")))
            print("> " + "\n> ".join(c.output.get("summary").split("\n")))

    print("* MERGIFY LIVE MATCHES:")
    match = pull_request_rules.get_pull_request_rule(mp)
    summary_title, summary = actions_runner.gen_summary(
        "refresh", {}, mp, match)
    print("> %s" % summary_title)
    print(summary)

    return g, p
Exemple #15
0
def report(url):
    path = url.replace("https://github.com/", "")
    try:
        owner, repo, _, pull_number = path.split("/")
    except ValueError:
        print(f"Wrong URL: {url}")
        return
    slug = owner + "/" + repo

    try:
        client = github.get_client(owner, repo)
    except exceptions.MergifyNotInstalled:
        print("* Mergify is not installed there")
        return

    print("* INSTALLATION ID: %s" % client.auth.installation["id"])

    cached_sub, db_sub = utils.async_run(
        sub_utils.get_subscription(client.auth.owner_id),
        sub_utils._retrieve_subscription_from_db(client.auth.owner_id),
    )
    print("* SUBSCRIBED (cache/db): %s / %s" %
          (cached_sub["subscription_active"], db_sub["subscription_active"]))
    report_sub(client.auth.installation["id"], slug, cached_sub,
               "ENGINE-CACHE")
    report_sub(client.auth.installation["id"], slug, db_sub, "DASHBOARD")

    utils.async_run(report_worker_status(client.auth.owner))

    pull_raw = client.item(f"pulls/{pull_number}")
    ctxt = context.Context(client, pull_raw, cached_sub, [{
        "event_type": "mergify-debugger",
        "data": {}
    }])

    q = queue.Queue.from_context(ctxt)
    print("QUEUES: %s" % ", ".join([f"#{p}" for p in q.get_pulls()]))

    print("* REPOSITORY IS %s" %
          "PRIVATE" if ctxt.pull["base"]["repo"]["private"] else "PUBLIC")

    print("* CONFIGURATION:")
    try:
        filename, mergify_config_content = rules.get_mergify_config_content(
            ctxt)
    except rules.NoRules:  # pragma: no cover
        print(".mergify.yml is missing")
        pull_request_rules = None
    else:
        print(f"Config filename: {filename}")
        print(mergify_config_content.decode())
        try:
            mergify_config = rules.UserConfigurationSchema(
                mergify_config_content)
        except rules.InvalidRules as e:  # pragma: no cover
            print("configuration is invalid %s" % str(e))
        else:
            pull_request_rules_raw = mergify_config[
                "pull_request_rules"].as_dict()
            pull_request_rules = rules.PullRequestRules.from_list(
                pull_request_rules_raw["rules"] + engine.MERGIFY_RULE["rules"])

    print("* PULL REQUEST:")
    pr_data = dict(ctxt.pull_request.items())
    pprint.pprint(pr_data, width=160)

    print("is_behind: %s" % ctxt.is_behind)

    print("mergeable_state: %s" % ctxt.pull["mergeable_state"])

    print("* MERGIFY LAST CHECKS:")
    for c in ctxt.pull_engine_check_runs:
        print("[%s]: %s | %s" %
              (c["name"], c["conclusion"], c["output"].get("title")))
        print("> " + "\n> ".join(c["output"].get("summary").split("\n")))

    if pull_request_rules is not None:
        print("* MERGIFY LIVE MATCHES:")
        match = pull_request_rules.get_pull_request_rule(ctxt)
        summary_title, summary = actions_runner.gen_summary(ctxt, match)
        print("> %s" % summary_title)
        print(summary)

    return ctxt