Skip to content

Commit

Permalink
Merge pull request #769 from conda-forge/rerender-pr-status
Browse files Browse the repository at this point in the history
feat: set rerender pr status
  • Loading branch information
beckermr authored Nov 9, 2024
2 parents cd43445 + f5cbb32 commit 69f5641
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 39 deletions.
11 changes: 9 additions & 2 deletions .github/workflows/webservices-workflow-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ on:
description: 'a unique identifier for this run'
required: true
type: string
sha:
description: 'the sha of the commit to run on'
required: false
type: string
default: 'null'

env:
PY_COLORS: 1
Expand Down Expand Up @@ -78,7 +83,8 @@ jobs:
conda-forge-webservices-init-task \
--task=${{ inputs.task }} \
--repo=${{ inputs.repo }} \
--pr-number=${{ inputs.pr_number }}
--pr-number=${{ inputs.pr_number }} \
--sha=${{ inputs.sha }}
env:
GH_TOKEN: ${{ secrets.CF_ADMIN_GITHUB_TOKEN }}

Expand Down Expand Up @@ -122,7 +128,8 @@ jobs:
--repo=${{ inputs.repo }} \
--pr-number=${{ inputs.pr_number }} \
--task-data-dir=${{ github.workspace }}/task-data \
--requested-version=${{ inputs.requested_version }}
--requested-version=${{ inputs.requested_version }} \
--sha=${{ inputs.sha }}
- name: upload task data
id: upload-task-data
Expand Down
43 changes: 42 additions & 1 deletion conda_forge_webservices/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
LINT_VIA_GHA,
)
from .update_teams import update_team
from .utils import ALLOWED_CMD_NON_FEEDSTOCKS, with_action_url
from .utils import (
ALLOWED_CMD_NON_FEEDSTOCKS,
with_action_url,
get_workflow_run_from_uid,
)
from ._version import __version__
from conda_forge_webservices.tokens import (
get_app_token_for_webservices_only,
Expand Down Expand Up @@ -986,9 +990,37 @@ def make_rerender_dummy_commit(repo):
return True


def set_rerender_pr_status(repo, pr_num, status, target_url=None, sha=None):
if target_url is not None:
kwargs = {"target_url": target_url}
else:
kwargs = {}

if sha is None:
pull = repo.get_pull(int(pr_num))
sha = pull.head.sha
commit = repo.get_commit(sha)

if status == "success":
msg = "Rerendering successful."
elif status == "failure" or status == "error":
msg = "Rerendering failed."
else:
msg = "Rerendering in progress..."

commit.create_status(
status,
description=msg,
context="conda-forge-rerendering-service",
**kwargs,
)


def rerender(full_name, pr_num):
gh = get_gh_client()
repo = gh.get_repo(full_name)
pull = repo.get_pull(int(pr_num))
sha = pull.head.sha

inject_app_token_into_feedstock(full_name, repo=repo)
inject_app_token_into_feedstock_readonly(full_name, repo=repo)
Expand All @@ -1007,8 +1039,17 @@ def rerender(full_name, pr_num):
"pr_number": str(pr_num),
"container_tag": ref,
"uuid": uid,
"sha": sha,
},
)
if running:
run = get_workflow_run_from_uid(workflow, uid, ref)
if run:
target_url = run.html_url
else:
target_url = None

set_rerender_pr_status(repo, pr_num, "pending", target_url=target_url, sha=sha)

return not running

Expand Down
37 changes: 31 additions & 6 deletions conda_forge_webservices/github_actions_integration/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
get_recipes_for_linting,
)
from .version_updating import update_version, update_pr_title
from conda_forge_webservices.commands import set_rerender_pr_status


LOGGER = logging.getLogger(__name__)
Expand All @@ -55,7 +56,8 @@ def _pull_docker_image():
@click.option("--task", required=True, type=str)
@click.option("--repo", required=True, type=str)
@click.option("--pr-number", required=True, type=str)
def main_init_task(task, repo, pr_number):
@click.option("--sha", required=False, type=str, default=None)
def main_init_task(task, repo, pr_number, sha):
logging.basicConfig(level=logging.INFO)

action_desc = f"task `{task}` for conda-forge/{repo}#{pr_number}"
Expand All @@ -69,8 +71,11 @@ def main_init_task(task, repo, pr_number):
elif task == "lint":
_, gh = create_api_sessions()
gh_repo = gh.get_repo(f"conda-forge/{repo}")
pr = gh_repo.get_pull(int(pr_number))
set_pr_status(pr.base.repo, pr.head.sha, "pending", target_url=None)
target_url = (
f"https://github.com/conda-forge/conda-forge-webservices/"
f"actions/runs/{os.environ['GITHUB_RUN_ID']}"
)
set_pr_status(gh_repo, sha, "pending", target_url=target_url)
else:
raise ValueError(f"Task `{task}` is not valid!")

Expand All @@ -81,7 +86,8 @@ def main_init_task(task, repo, pr_number):
@click.option("--pr-number", required=True, type=str)
@click.option("--task-data-dir", required=True, type=str)
@click.option("--requested-version", required=False, type=str, default=None)
def main_run_task(task, repo, pr_number, task_data_dir, requested_version):
@click.option("--sha", required=False, type=str, default=None)
def main_run_task(task, repo, pr_number, task_data_dir, requested_version, sha):
setup_logging(level="DEBUG")

LOGGER.info("running task `%s` for conda-forge/%s#%s", task, repo, pr_number)
Expand All @@ -100,7 +106,13 @@ def main_run_task(task, repo, pr_number, task_data_dir, requested_version):
git_repo.git.switch(f"pull/{pr_number}/head")
prev_head = git_repo.active_branch.commit.hexsha

task_data = {"task": task, "repo": repo, "pr_number": pr_number, "task_results": {}}
task_data = {
"task": task,
"repo": repo,
"pr_number": pr_number,
"sha": sha,
"task_results": {},
}

if task == "rerender":
_pull_docker_image()
Expand Down Expand Up @@ -267,6 +279,7 @@ def main_finalize_task(task_data_dir):
repo = task_data["repo"]
pr_number = task_data["pr_number"]
task_results = task_data["task_results"]
sha_for_status = task_data["sha"]

LOGGER.info("finalizing task `%s` for conda-forge/%s#%s", task, repo, pr_number)
LOGGER.info("task results:")
Expand Down Expand Up @@ -354,6 +367,18 @@ def main_finalize_task(task_data_dir):
repo_name=full_repo_name,
close_pr_if_no_changes_or_errors=False,
)
status = "success" if not comment_push_error else "failure"
target_url = (
f"https://github.com/conda-forge/conda-forge-webservices/"
f"actions/runs/{os.environ['GITHUB_RUN_ID']}"
)
set_rerender_pr_status(
gh_repo,
int(pr_number),
status,
target_url=target_url,
sha=sha_for_status,
)

# if the pr was made by the bot, mark it as ready for review
if (
Expand Down Expand Up @@ -464,7 +489,7 @@ def main_finalize_task(task_data_dir):
gh, gh_repo, pr.number, task_results["lints"], task_results["hints"]
)

set_pr_status(pr.base.repo, pr.head.sha, status, target_url=msg.html_url)
set_pr_status(gh_repo, sha_for_status, status, target_url=msg.html_url)
print(f"Linter status: {status}")
print(f"Linter message:\n{msg.body}")

Expand Down
27 changes: 3 additions & 24 deletions conda_forge_webservices/linting.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import conda_smithy.lint_recipe

from conda_forge_webservices.tokens import get_gh_client
from conda_forge_webservices.utils import get_workflow_run_from_uid
from ._version import __version__

LOGGER = logging.getLogger("conda_forge_webservices.linting")
Expand All @@ -29,29 +30,6 @@ class LintInfo(TypedDict):
sha: str


def _get_workflow_run_from_uid(workflow, uid, ref):
for _ in range(10):
time.sleep(1)
run = _inner_get_workflow_run_from_uid(workflow, uid, ref)
if run:
return run
return None


def _inner_get_workflow_run_from_uid(workflow, uid, ref):
num_try = 0
max_try = 20
for run in workflow.get_runs(branch=ref, event="workflow_dispatch"):
if uid in run.name:
return run

num_try += 1
if num_try > max_try:
break

return None


def lint_via_github_actions(full_name: str, pr_num: int) -> bool:
gh = get_gh_client()
repo = gh.get_repo(full_name)
Expand All @@ -78,11 +56,12 @@ def lint_via_github_actions(full_name: str, pr_num: int) -> bool:
"pr_number": str(pr_num),
"container_tag": ref,
"uuid": uid,
"sha": sha,
},
)

if running:
run = _get_workflow_run_from_uid(workflow, uid, ref)
run = get_workflow_run_from_uid(workflow, uid, ref)
if run:
target_url = run.html_url
else:
Expand Down
24 changes: 24 additions & 0 deletions conda_forge_webservices/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import shutil
import time
import tempfile
from contextlib import contextmanager

Expand Down Expand Up @@ -48,3 +49,26 @@ def with_action_url(msg: str) -> str:
if action_url:
msg += f"\n\nGenerated by {action_url}"
return msg


def get_workflow_run_from_uid(workflow, uid, ref):
for _ in range(10):
time.sleep(1)
run = _inner_get_workflow_run_from_uid(workflow, uid, ref)
if run:
return run
return None


def _inner_get_workflow_run_from_uid(workflow, uid, ref):
num_try = 0
max_try = 100
for run in workflow.get_runs(branch=ref, event="workflow_dispatch"):
if uid in run.name:
return run

num_try += 1
if num_try > max_try:
break

return None
8 changes: 5 additions & 3 deletions tests/test_live_linter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import github

import conda_forge_webservices
from conda_forge_webservices.linting import _get_workflow_run_from_uid
from conda_forge_webservices.utils import get_workflow_run_from_uid
from conda_forge_webservices.github_actions_integration.linting import set_pr_status

TEST_CASES = [
Expand Down Expand Up @@ -95,6 +95,7 @@ def test_linter_pr(pytestconfig):
for pr_number, _, _ in TEST_CASES:
uid = uuid.uuid4().hex
pr = repo.get_pull(pr_number)
pr_sha = pr.head.sha
workflow = repo.get_workflow("webservices-workflow-dispatch.yml")
workflow_ran = workflow.create_dispatch(
ref=branch,
Expand All @@ -104,17 +105,18 @@ def test_linter_pr(pytestconfig):
"pr_number": str(pr_number),
"container_tag": conda_forge_webservices.__version__.replace("+", "."),
"uuid": uid,
"sha": pr_sha,
},
)
assert workflow_ran, f"Workflow did not run for PR {pr_number}!"
run = _get_workflow_run_from_uid(workflow, uid, branch)
run = get_workflow_run_from_uid(workflow, uid, branch)
if run:
target_url = run.html_url
else:
target_url = None
assert target_url is not None
print(f"target_url for PR {pr_number}: {target_url}", flush=True)
set_pr_status(repo, pr.head.sha, "pending", target_url=target_url)
set_pr_status(repo, pr_sha, "pending", target_url=target_url)

print("\nsleeping for four minutes to let the linter work...", flush=True)
tot = 0
Expand Down
27 changes: 24 additions & 3 deletions tests/test_live_rerender.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,48 @@

import conda_forge_webservices
import github
from conda_forge_webservices.utils import pushd
from conda_forge_webservices.utils import pushd, get_workflow_run_from_uid
from conda_forge_webservices.commands import set_rerender_pr_status

from conftest import _merge_main_to_branch


def _run_test(branch):
pr_number = 445
print("sending workflow dispatch event to rerender...", flush=True)
uid = uuid.uuid4().hex
gh = github.Github(auth=github.Auth.Token(os.environ["GH_TOKEN"]))
repo = gh.get_repo("conda-forge/conda-forge-webservices")
workflow = repo.get_workflow("webservices-workflow-dispatch.yml")
workflow.create_dispatch(
pr_sha = (
gh.get_repo("conda-forge/cf-autotick-bot-test-package-feedstock")
.get_pull(pr_number)
.head.sha
)
running = workflow.create_dispatch(
ref=branch,
inputs={
"task": "rerender",
"repo": "cf-autotick-bot-test-package-feedstock",
"pr_number": "445",
"pr_number": str(pr_number),
"container_tag": conda_forge_webservices.__version__.replace("+", "."),
"uuid": uid,
"sha": pr_sha,
},
)
assert running, f"Workflow dispatch failed for rerendering on PR {pr_number}!"
run = get_workflow_run_from_uid(workflow, uid, branch)
assert run, f"Workflow run not found for rerendering on PR {pr_number}!"
target_url = run.html_url
print(f"target_url for PR {pr_number}: {target_url}", flush=True)

set_rerender_pr_status(
gh.get_repo("conda-forge/cf-autotick-bot-test-package-feedstock"),
pr_number,
"pending",
target_url=target_url,
sha=pr_sha,
)

print("sleeping for four minutes to let the rerender happen...", flush=True)
tot = 0
Expand Down

0 comments on commit 69f5641

Please sign in to comment.