Skip to content

Commit

Permalink
Merge pull request #682 from conda-forge/revert-681-revert-680-revert…
Browse files Browse the repository at this point in the history
…-679-lint-gha

Revert "feat: move linting to GHA"
  • Loading branch information
beckermr authored Sep 21, 2024
2 parents cc9b767 + 21a26c2 commit c3f8257
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 198 deletions.
65 changes: 27 additions & 38 deletions conda_forge_webservices/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,11 @@
import logging

# from .utils import tmp_directory
from .linting import (
compute_lint_message,
comment_on_pr,
set_pr_status,
lint_via_github_actions,
LINT_VIA_GHA,
)
from .linting import compute_lint_message, comment_on_pr, set_pr_status
from .update_teams import update_team
from .utils import ALLOWED_CMD_NON_FEEDSTOCKS, with_action_url
from conda_forge_webservices.tokens import (
get_app_token_for_webservices_only,
get_gh_client,
inject_app_token_into_feedstock,
inject_app_token_into_feedstock_readonly,
)
Expand Down Expand Up @@ -155,7 +148,7 @@ def add_reaction(
def pr_comment(org_name, repo_name, issue_num, comment, comment_id=None):
if not COMMAND_PREFIX.search(comment):
return
gh = get_gh_client()
gh = github.Github(get_app_token_for_webservices_only())
repo = gh.get_repo(f"{org_name}/{repo_name}")
pr = repo.get_pull(int(issue_num))
pr_detailed_comment(
Expand Down Expand Up @@ -185,8 +178,10 @@ def pr_detailed_comment(
if not (repo_name.endswith("-feedstock") or is_allowed_cmd):
return

GH_TOKEN = get_app_token_for_webservices_only()

if not is_allowed_cmd:
gh = get_gh_client()
gh = github.Github(GH_TOKEN)
repo = gh.get_repo(f"{org_name}/{repo_name}")
pull = repo.get_pull(int(pr_num))
if pull.head.repo.full_name.split("/")[0] == "conda-forge":
Expand All @@ -203,7 +198,7 @@ def pr_detailed_comment(
pull.create_issue_comment(message)

if RESTART_CI.search(comment):
gh = get_gh_client()
gh = github.Github(GH_TOKEN)
repo = gh.get_repo(f"{org_name}/{repo_name}")
if comment_id is not None or review_id is not None:
add_reaction("rocket", repo, pr_num, comment_id, review_id)
Expand All @@ -224,7 +219,7 @@ def pr_detailed_comment(
else:
team = repo_name.replace("-feedstock", "")

gh = get_gh_client()
gh = github.Github(GH_TOKEN)
repo = gh.get_repo(f"{org_name}/{repo_name}")
if comment_id is not None or review_id is not None:
add_reaction("rocket", repo, pr_num, comment_id, review_id)
Expand All @@ -237,7 +232,7 @@ def pr_detailed_comment(
pull.create_issue_comment(message)

if not is_allowed_cmd and RERUN_BOT.search(comment):
gh = get_gh_client()
gh = github.Github(GH_TOKEN)
repo = gh.get_repo(f"{org_name}/{repo_name}")
if comment_id is not None or review_id is not None:
add_reaction("rocket", repo, pr_num, comment_id, review_id)
Expand All @@ -257,17 +252,16 @@ def pr_detailed_comment(
return

if comment_id is not None or review_id is not None:
repo = get_gh_client().get_repo(f"{org_name}/{repo_name}")
repo = github.Github(GH_TOKEN).get_repo(f"{org_name}/{repo_name}")
add_reaction("rocket", repo, pr_num, comment_id, review_id)

tmp_dir = None
try:
tmp_dir = tempfile.mkdtemp("_recipe")

gh_token = get_app_token_for_webservices_only()
feedstock_dir = os.path.join(tmp_dir, repo_name)
repo_url = (
f"https://x-access-token:{gh_token}@github.com/{pr_owner}/{pr_repo}.git"
f"https://x-access-token:{GH_TOKEN}@github.com/{pr_owner}/{pr_repo}.git"
)

for _git_try_num in range(NUM_GIT_CLONE_TRIES):
Expand Down Expand Up @@ -348,7 +342,7 @@ def pr_detailed_comment(
""").format(doc_url) # noqa

if message is not None:
gh = get_gh_client()
gh = github.Github(GH_TOKEN)
gh_repo = gh.get_repo(f"{org_name}/{repo_name}")
pull = gh_repo.get_pull(int(pr_num))
pull.create_issue_comment(message)
Expand Down Expand Up @@ -391,6 +385,8 @@ def issue_comment(org_name, repo_name, issue_num, title, comment, comment_id=Non
if not any(command.search(text) for command in issue_commands):
return

APP_GH_TOKEN = get_app_token_for_webservices_only()

# sometimes the webhook outpaces other bits of the API so we try a bit
for i in range(NUM_GH_API_TRIES):
try:
Expand All @@ -409,7 +405,7 @@ def issue_comment(org_name, repo_name, issue_num, title, comment, comment_id=Non
raise e

# these are used when the app takes actions
app_repo = get_gh_client().get_repo(f"{org_name}/{repo_name}")
app_repo = github.Github(APP_GH_TOKEN).get_repo(f"{org_name}/{repo_name}")
app_issue = app_repo.get_issue(int(issue_num))

if comment_id is not None:
Expand Down Expand Up @@ -462,12 +458,11 @@ def issue_comment(org_name, repo_name, issue_num, title, comment, comment_id=Non
gh,
)

gh_token = get_app_token_for_webservices_only()
feedstock_dir = os.path.join(tmp_dir, repo_name)
repo_url = "https://x-access-token:{}@github.com/{}/{}.git".format(
os.environ["GH_TOKEN"], forked_user, repo_name
)
upstream_repo_url = f"https://x-access-token:{gh_token}@github.com/{org_name}/{repo_name}.git"
upstream_repo_url = f"https://x-access-token:{APP_GH_TOKEN}@github.com/{org_name}/{repo_name}.git"

for _git_try_num in range(NUM_GIT_CLONE_TRIES):
try:
Expand Down Expand Up @@ -976,7 +971,7 @@ def make_rerender_dummy_commit(repo):


def rerender(full_name, pr_num):
gh = get_gh_client()
gh = github.Github(get_app_token_for_webservices_only())
repo = gh.get_repo(full_name)

inject_app_token_into_feedstock(full_name, repo=repo)
Expand All @@ -989,7 +984,7 @@ def rerender(full_name, pr_num):


def update_version(full_name, pr_num, input_ver):
gh = get_gh_client()
gh = github.Github(get_app_token_for_webservices_only())
repo = gh.get_repo(full_name)

inject_app_token_into_feedstock(full_name, repo=repo)
Expand Down Expand Up @@ -1028,23 +1023,17 @@ def make_noarch(repo):

def relint(owner, repo_name, pr_num):
pr = int(pr_num)
if LINT_VIA_GHA:
lint_via_github_actions(
f"{owner}/{repo_name}",
pr,
)
lint_info = compute_lint_message(
owner,
repo_name,
pr,
repo_name == "staged-recipes",
)
if not lint_info:
LOGGER.warning("Linting was skipped.")
else:
lint_info = compute_lint_message(
owner,
repo_name,
pr,
repo_name == "staged-recipes",
)
if not lint_info:
LOGGER.warning("Linting was skipped.")
else:
msg = comment_on_pr(owner, repo_name, pr, lint_info["message"], force=True)
set_pr_status(owner, repo_name, lint_info, target_url=msg.html_url)
msg = comment_on_pr(owner, repo_name, pr, lint_info["message"], force=True)
set_pr_status(owner, repo_name, lint_info, target_url=msg.html_url)


def add_bot_rerun_label(repo, pr_num):
Expand Down
10 changes: 4 additions & 6 deletions conda_forge_webservices/feedstock_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@
import binstar_client.errors

from .utils import parse_conda_pkg
from conda_forge_webservices.tokens import (
get_app_token_for_webservices_only,
get_gh_client,
)
from conda_forge_webservices.tokens import get_app_token_for_webservices_only

LOGGER = logging.getLogger("conda_forge_webservices.feedstock_outputs")

Expand Down Expand Up @@ -220,7 +217,8 @@ def _add_feedstock_output(
feedstock: str,
pkg_name: str,
):
gh = get_gh_client()
gh_token = get_app_token_for_webservices_only()
gh = github.Github(auth=github.Auth.Token(gh_token))
repo = gh.get_repo("conda-forge/feedstock-outputs")
try:
contents = repo.get_contents(_get_sharded_path(pkg_name))
Expand Down Expand Up @@ -433,7 +431,7 @@ def comment_on_outputs_copy(feedstock, git_sha, errors, valid, copied):
if not feedstock.endswith("-feedstock"):
return None

gh = get_gh_client()
gh = github.Github(get_app_token_for_webservices_only())

team_name = feedstock[: -len("-feedstock")]

Expand Down
8 changes: 3 additions & 5 deletions conda_forge_webservices/feedstocks_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import tempfile
import shutil
import logging
import github

from conda_forge_webservices.tokens import (
get_app_token_for_webservices_only,
get_gh_client,
)
from conda_forge_webservices.tokens import get_app_token_for_webservices_only
from conda_forge_webservices.utils import with_action_url

LOGGER = logging.getLogger("conda_forge_webservices.feedstocks_service")
Expand Down Expand Up @@ -45,7 +43,7 @@ def update_feedstock(org_name, repo_name):
# sometimes the webhook outpaces other bits of the API so we try a bit
for i in range(5):
try:
gh = get_gh_client()
gh = github.Github(gh_token)
default_branch = gh.get_repo(f"{org_name}/{repo_name}").default_branch
break
except Exception as e:
Expand Down
50 changes: 13 additions & 37 deletions conda_forge_webservices/linting.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@
from typing import TypedDict

from git import GitCommandError, Repo
import github
import conda_smithy.lint_recipe

from conda_forge_webservices.tokens import get_gh_client
from conda_forge_webservices.tokens import get_app_token_for_webservices_only

LOGGER = logging.getLogger("conda_forge_webservices.linting")
SKIP_MSGS = [
"[ci skip]",
"[skip ci]",
"[lint skip]",
"[skip lint]",
]
LINT_VIA_GHA = True


class LintInfo(TypedDict):
Expand All @@ -27,30 +21,6 @@ class LintInfo(TypedDict):
sha: str


def lint_via_github_actions(full_name: str, pr_num: int) -> bool:
gh = get_gh_client()
repo = gh.get_repo(full_name)
repo_owner, repo_name = full_name.split("/")
pr = repo.get_pull(pr_num)
sha = pr.head.sha
commit = gh.get_repo(pr.head.repo.full_name).get_git_commit(sha)
commit_msg = commit.message

should_skip = any([msg in commit_msg for msg in SKIP_MSGS])
if should_skip:
return False

running = repo.create_repository_dispatch(
"lint",
client_payload={"pr": pr_num},
)

if running:
_set_pr_status(repo_owner, repo_name, sha, "pending")

return running


def find_recipes(path: Path) -> list[Path]:
"""
Returns all `meta.yaml` and `recipe.yaml` files in the given path.
Expand Down Expand Up @@ -185,7 +155,7 @@ def _set_pr_status(
else:
kwargs = {}

gh = get_gh_client()
gh = github.Github(get_app_token_for_webservices_only())
user = gh.get_user(owner)
repo = user.get_repo(repo_name)
commit = repo.get_commit(sha)
Expand All @@ -204,7 +174,7 @@ def compute_lint_message(
ignore_base: bool = False,
set_pending_status: bool = True,
) -> LintInfo | None:
gh = get_gh_client()
gh = github.Github(get_app_token_for_webservices_only())

owner = gh.get_user(repo_owner)
remote_repo = owner.get_repo(repo_name)
Expand Down Expand Up @@ -244,8 +214,14 @@ def compute_lint_message(
sha = str(ref_head.commit.hexsha)

# Check if the linter is skipped via the commit message.
skip_msgs = [
"[ci skip]",
"[skip ci]",
"[lint skip]",
"[skip lint]",
]
commit_msg = repo.commit(sha).message
should_skip = any([msg in commit_msg for msg in SKIP_MSGS])
should_skip = any([msg in commit_msg for msg in skip_msgs])
if should_skip:
return None

Expand Down Expand Up @@ -309,7 +285,7 @@ def comment_on_pr(
force: bool = False,
search: str | None = None,
):
gh = get_gh_client()
gh = github.Github(get_app_token_for_webservices_only())

user = gh.get_user(owner)
repo = user.get_repo(repo_name)
Expand Down Expand Up @@ -348,7 +324,7 @@ def comment_on_pr(
def set_pr_status(
owner: str, repo_name: str, lint_info: LintInfo, target_url: str | None = None
):
gh = get_gh_client()
gh = github.Github(get_app_token_for_webservices_only())

user = gh.get_user(owner)
repo = user.get_repo(repo_name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,21 @@ def test_ok_recipe_above_good_recipe():
lint = compute_lint_message(
"conda-forge", "conda-forge-webservices", 54, set_pending_status=False
)
assert lint["message"].startswith(expected_message)
assert expected_message == lint["message"]


def test_ok_recipe_beside_good_recipe():
expected_message = textwrap.dedent("""
Hi! This is the friendly automated conda-forge-linting service.
I just wanted to let you know that I linted all conda-recipes in your PR (```recipe/blah/meta.yaml```, ```recipe/meta.yaml```, ```recipes/recipe/meta.yaml```) and found it was in an excellent condition.
I just wanted to let you know that I linted all conda-recipes in your PR (```recipe/meta.yaml```, ```recipes/recipe/meta.yaml```) and found it was in an excellent condition.
""") # noqa

lint = compute_lint_message(
"conda-forge", "conda-forge-webservices", 62, set_pending_status=False
)
assert lint["message"].startswith(expected_message)
assert expected_message == lint["message"]


def test_ok_recipe_above_ignored_good_recipe():
Expand All @@ -94,21 +94,21 @@ def test_ok_recipe_above_ignored_good_recipe():
lint = compute_lint_message(
"conda-forge", "conda-forge-webservices", 54, True, set_pending_status=False
)
assert lint["message"].startswith(expected_message)
assert expected_message == lint["message"]


def test_ok_recipe_beside_ignored_good_recipe():
expected_message = textwrap.dedent("""
Hi! This is the friendly automated conda-forge-linting service.
I just wanted to let you know that I linted all conda-recipes in your PR (```recipe/blah/meta.yaml```, ```recipe/meta.yaml```) and found it was in an excellent condition.
I just wanted to let you know that I linted all conda-recipes in your PR (```recipe/meta.yaml```) and found it was in an excellent condition.
""") # noqa

lint = compute_lint_message(
"conda-forge", "conda-forge-webservices", 62, True, set_pending_status=False
)
assert lint["message"].startswith(expected_message)
assert expected_message == lint["message"]


def test_conflict_ok_recipe():
Expand Down
Loading

0 comments on commit c3f8257

Please sign in to comment.