mirror of
https://github.com/ansible/ansible-documentation.git
synced 2026-03-27 13:28:51 +07:00
* pr_labeler: improve create_boilerplate_comment logging (cherry picked from commit5730ba9a01) * pr_labeler: add --force-process-closed flag (cherry picked from commit44ffe0f210) * pr_labeler: add warning for porting_guides changes This adds a warning message when PRs are created that edit porting_guides by someone outside of the Release Management WG. These files are automatically generated during the ansible release process and should not be modified. Fixes: https://github.com/ansible/ansible-documentation/issues/503 (cherry picked from commitd2e6625e8b) * pr_labeler: use @release-management-wg team for porting_guide check Instead of hardcoding the list of release managers, we can use the Github API to retrieve the members of the `@ansible/release-management-wg` team. (cherry picked from commitdddfd7eb55) * pr_labeler: exempt bots from porting_guide check For example, patchback is not a release manager, but we still want it to backport Porting Guide PRs. (cherry picked from commit746662c255) * pr_labeler: improve porting_guide_changes template wording Co-authored-by: Sandra McCann <samccann@redhat.com> (cherry picked from commit95ece7e9d6) * pr_labeler: refactor new_contributor_welcome code (#990) * pr_labeler: add GlobalArgs.full_repo property * pr_labeler: refactor new_contributor_welcome code As of https://github.com/ansible/ansible-documentation/issues/69, the pr_labeler responds with a welcome message when an issue or PR is opened by a new contributor. It turns out this never actually worked properly. The previous method that relied on Github's `author_association` flag did not work with the app token that the pr_labeler uses. This refactors the code to figure out whether a user is a new contributor by searching the list of issues and PRs. Fixes: https://github.com/ansible/ansible-documentation/issues/204 * pr_labeler: address potential race condition (cherry picked from commit763815d1ad) * Bump actions/setup-python from 4 to 5 (#966) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... (cherry picked from commit466b1fdc43) * pr_labeler: re-architect triager script (#1882) This commit reorganizes the issue/PR triager script and updates the workflow to run more efficiently. - Make the script a proper Python package instead of an unwieldy single file - Use locked dependencies and UV to decrease workflow runtime to under 10 seconds. (cherry picked from commit7138e42716) (cherry picked from commit1cf9f7917b) --------- Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
118 lines
3.1 KiB
Python
118 lines
3.1 KiB
Python
# Copyright (C) 2023 Maxwell G <maxwell@gtmx.me>
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
"""
|
|
Utilities for working with the Github API
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
from contextlib import suppress
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
import github
|
|
import github.Auth
|
|
import github.Issue
|
|
import github.PullRequest
|
|
import github.Repository
|
|
|
|
from .cli_context import IssueLabelerCtx, IssueOrPrCtx
|
|
from .utils import log
|
|
|
|
if TYPE_CHECKING:
|
|
from typing_extensions import TypeAlias
|
|
|
|
|
|
IssueOrPr: TypeAlias = "github.Issue.Issue | github.PullRequest.PullRequest"
|
|
|
|
|
|
def get_repo(
|
|
full_repo: str,
|
|
authed: bool = True,
|
|
) -> tuple[github.Github, github.Repository.Repository]:
|
|
"""
|
|
Create a Github client and return a `github.Repository.Repository` object
|
|
|
|
Args:
|
|
full_repo: OWNER/NAME of the repository
|
|
authed:
|
|
Whether to create an authenticated Github client with the
|
|
`$GITHUB_TOKEN` environment variable as the key
|
|
"""
|
|
gclient = github.Github(
|
|
auth=github.Auth.Token(os.environ["GITHUB_TOKEN"]) if authed else None,
|
|
)
|
|
repo_obj = gclient.get_repo(full_repo)
|
|
return gclient, repo_obj
|
|
|
|
|
|
def get_event_info() -> dict[str, Any]:
|
|
"""
|
|
Load Github event JSON data from `$event_data`
|
|
"""
|
|
event_json = os.environ.get("event_json")
|
|
if not event_json:
|
|
return {}
|
|
with suppress(json.JSONDecodeError):
|
|
return json.loads(event_json)
|
|
return {}
|
|
|
|
|
|
# Operations
|
|
|
|
|
|
def get_team_members(ctx: IssueOrPrCtx, team: str) -> list[str]:
|
|
"""
|
|
Get the members of a Github team
|
|
"""
|
|
return [
|
|
user.login
|
|
for user in ctx.client.get_organization(ctx.repo.organization.login)
|
|
.get_team_by_slug(team)
|
|
.get_members()
|
|
]
|
|
|
|
|
|
def create_comment(ctx: IssueOrPrCtx, body: str) -> None:
|
|
if ctx.dry_run:
|
|
return
|
|
if isinstance(ctx, IssueLabelerCtx):
|
|
ctx.issue.create_comment(body)
|
|
else:
|
|
ctx.pr.create_issue_comment(body)
|
|
|
|
|
|
def is_new_contributor_assoc(ctx: IssueOrPrCtx) -> bool:
|
|
"""
|
|
Determine whether a user has previously contributed.
|
|
Requires authentication as a regular user and does not work with an app
|
|
token.
|
|
"""
|
|
author_association = ctx.event_member.get(
|
|
"author_association", ctx.member.raw_data["author_association"]
|
|
)
|
|
log(ctx, "author_association is", author_association)
|
|
return author_association in {"FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR"}
|
|
|
|
|
|
def is_new_contributor_manual(ctx: IssueOrPrCtx) -> bool:
|
|
"""
|
|
Determine whether a user has previously opened an issue or PR in this repo
|
|
without needing special API access.
|
|
"""
|
|
query_data = {
|
|
"repo": "ansible/ansible-documentation",
|
|
"author": ctx.issue.user.login,
|
|
# Avoid potential race condition where a new contributor opens multiple
|
|
# PRs or issues at once.
|
|
# Better to welcome twice than not at all.
|
|
"is": "closed",
|
|
}
|
|
issues = ctx.client.search_issues("", **query_data)
|
|
for issue in issues:
|
|
if issue.number != ctx.issue.number:
|
|
return False
|
|
return True
|