diff --git a/.github/workflows/AutoArchiving.yml b/.github/workflows/AutoArchiving.yml index 5c6913e..c8bbb40 100644 --- a/.github/workflows/AutoArchiving.yml +++ b/.github/workflows/AutoArchiving.yml @@ -99,6 +99,10 @@ jobs: - name: Add and commit changes run: | bash ./rn_issues_auto_archiving/push_document.sh + + - name: Send archiving success comment + run: | + python ./rn_issues_auto_archiving/archiving_success.py diff --git a/rn_issues_auto_archiving/archiving_success.py b/rn_issues_auto_archiving/archiving_success.py new file mode 100644 index 0000000..32af2ed --- /dev/null +++ b/rn_issues_auto_archiving/archiving_success.py @@ -0,0 +1,85 @@ +import json +import os +from pathlib import Path + +from shared.log import Log +from shared.issue_info import IssueInfo +from shared.get_args import get_value_from_args +from shared.issue_info import IssueInfoJson +from shared.json_dumps import json_dumps +from shared.env import (Env, + should_run_in_local + ) +from auto_archiving.send_comment import send_comment +from issue_processor.issue_platform import Gitlab, Github + + +def main(): + if should_run_in_local(): + print(Log.non_platform_action_env) + from dotenv import load_dotenv + load_dotenv() + + output_path = os.environ[Env.ISSUE_OUTPUT_PATH] + issue_repository = os.environ[Env.ISSUE_REPOSITORY] + token = os.environ[Env.TOKEN] + + issue_info_json: IssueInfoJson + issue_info: IssueInfo + try: + issue_info_json = json.loads( + Path(output_path + ).read_text(encoding="utf-8") + ) + print(Log.print_issue_info + .format(issue_info=json_dumps( + IssueInfoJson.remove_sensitive_info(issue_info_json) + ))) + issue_info = IssueInfo( + reopen_info=IssueInfo.ReopenInfo( + **issue_info_json.pop("reopen_info") + ), + **issue_info_json + ) + except FileNotFoundError: + print(Log.issue_output_not_found) + return + + http_header: dict[str, str] + if issue_info.platform_type == Github.name: + http_header = Github.create_http_header( + token=token + ) + elif issue_info.platform_type == Gitlab.name: + http_header = Gitlab.create_http_header( + token=token + ) + else: + raise ValueError( + Log.unknown_platform_type + .format( + platform_type=issue_info.platform_type + )) + try: + send_comment( + comment_url=issue_info.reopen_info.comment_url, + http_header=http_header, + message=Log.issue_archived_success.format( + issue_id=issue_info.issue_id, + issue_repository=issue_repository + ) + ) + except Exception as exc: + # 归档成功评论发送失败并不重要,失败就失败了 + # 如果是一开始流水线就有权限或者是链路问题, + # 那么前面的流程就会报错 + # 也不会执行到这里 + print(Log.send_comment_failed + .format( + exc=str(exc) + )) + print(Log.job_done) + + +if __name__ == "__main__": + main() diff --git a/rn_issues_auto_archiving/auto_archiving_main.py b/rn_issues_auto_archiving/auto_archiving_main.py index bb38eb4..5e938a5 100644 --- a/rn_issues_auto_archiving/auto_archiving_main.py +++ b/rn_issues_auto_archiving/auto_archiving_main.py @@ -105,11 +105,8 @@ def main(): issue_info.ci_event_type in CiEventType.manual ) ) - - comment_message = Log.issue_archived_success.format( - issue_id=issue_info.issue_id, - issue_repository=issue_repository - ) + # 由于后续还有push步骤,发送归档成功的评论不能在这里完成了 + enable_send_comment = False except Exception as exc: exceptions.append(exc) comment_message = ErrorMessage.archiving_failed.format( @@ -160,7 +157,6 @@ def main(): comment_url=issue_info.reopen_info.comment_url, message=comment_message ) - except Exception as exc_: exceptions.append(exc_) print(ErrorMessage.send_comment_failed diff --git a/rn_issues_auto_archiving/issue_processor/issue_platform.py b/rn_issues_auto_archiving/issue_processor/issue_platform.py index 54c96e1..da6990a 100644 --- a/rn_issues_auto_archiving/issue_processor/issue_platform.py +++ b/rn_issues_auto_archiving/issue_processor/issue_platform.py @@ -60,7 +60,6 @@ class PlatformEnvironments(): class Platform(ABC): - @staticmethod def issue_number_to_int(issue_number: str): if not issue_number.isdigit(): @@ -182,6 +181,7 @@ def __init__(self): self._http_header: dict[str, str] self._http_client: httpx.Client self._ci_event_type: str + self._platform_type: str def http_request( self, @@ -452,6 +452,7 @@ def issue_content_to_json( introduced_version=introduced_version, archive_version=archive_version, ci_event_type=self._ci_event_type, + platform_type=self._platform_type, reopen_info=IssueInfoJson.ReopenInfo( http_header=self._http_header, reopen_url=self._urls.issue_url, @@ -485,6 +486,7 @@ def issue_content_to_json( class Github(Platform): + name = "github" @staticmethod def create_http_header(token: str) -> dict[str, str]: @@ -586,6 +588,7 @@ def _init_http_client(self) -> None: def __init__(self): super().__init__() + self._platform_type = Github.name self._read_platform_environments() self._init_http_client() @@ -671,6 +674,29 @@ def close(self): class Gitlab(Platform): + name = "gitlab" + + @staticmethod + def should_issue_type_webhook() -> bool: + '''Gitlab流水线通过webhook触发流水线, + 且无法在流水线测区分webhook事件, + 可能会遇到非Issue事件触发的webhook触发了自动归档流水线 + (例如push事件webhook触发的自动部署流水线) + gitlab webhook事件类型详见: + https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#push-events + ''' + try: + webhook_payload = json.loads( + os.environ[Env.WEBHOOK_PAYLOAD]) + if webhook_payload["event_name"] == "issue": + print(Log.issue_type_webhook_detected) + return True + else: + print(Log.other_type_webhook_detected) + return False + except KeyError: + # 如果读取不到环境变量,说明是github流水线环境 + return True @staticmethod def create_http_header(token: str) -> dict[str, str]: @@ -817,6 +843,7 @@ def _init_http_client(self) -> None: def __init__(self): super().__init__() + self._platform_type = Gitlab.name self._read_platform_environments() self._init_http_client() diff --git a/rn_issues_auto_archiving/issue_processor_main.py b/rn_issues_auto_archiving/issue_processor_main.py index 57d3793..c8fbfc7 100644 --- a/rn_issues_auto_archiving/issue_processor_main.py +++ b/rn_issues_auto_archiving/issue_processor_main.py @@ -20,11 +20,6 @@ # 所以并没有实现黑名单的功能 -def Exit(): - print(Log.job_done) - exit(0) - - def main() -> None: if os.environ[Env.CI_EVENT_TYPE] in CiEventType.manual: print(Log.running_ci_by_manual) @@ -41,6 +36,9 @@ def main() -> None: from dotenv import load_dotenv load_dotenv() + if not Gitlab.should_issue_type_webhook(): + return + test_platform_type = get_value_from_args( short_arg="-pt", long_arg="--platform-type", @@ -57,13 +55,13 @@ def main() -> None: else: print(Log.get_test_platform_type .format(test_platform_type=test_platform_type)) - if test_platform_type == "github": + if test_platform_type == Github.name: platform = Github() - elif test_platform_type == "gitlab": + elif test_platform_type == Gitlab.name: try: platform = Gitlab() except WebhookPayloadError: - Exit() + return else: print(Log.unexpected_platform_type .format( @@ -77,11 +75,11 @@ def main() -> None: if (not platform.should_ci_running_in_manual and platform.should_issue_state_open): print(Log.issue_state_is_open) - Exit() - + return + if platform.should_issue_state_update: print(Log.issue_state_is_update) - Exit() + return platform.init_issue_info_from_platform() @@ -142,7 +140,7 @@ def main() -> None: config.white_list.labels ): print(Log.not_archive_issue) - Exit() + return archive_version = platform.parse_archive_version( archive_version_list ) @@ -160,7 +158,7 @@ def main() -> None: if (platform.should_ci_running_in_manual and platform.should_issue_state_open): platform.close_issue() - + print(Log.job_done) except ( ArchiveBaseError ) as exc: diff --git a/rn_issues_auto_archiving/push_document.py b/rn_issues_auto_archiving/push_document.py index 8dece78..41eaed3 100644 --- a/rn_issues_auto_archiving/push_document.py +++ b/rn_issues_auto_archiving/push_document.py @@ -15,7 +15,6 @@ from auto_archiving.http_request import http_request from issue_processor.issue_platform import Gitlab from shared.issue_info import IssueInfoJson -from shared.issue_state import IssueState def get_issue_id_from_issue_info(webhook_path: str) -> int: diff --git a/rn_issues_auto_archiving/shared/issue_info.py b/rn_issues_auto_archiving/shared/issue_info.py index a18d089..17ceec6 100644 --- a/rn_issues_auto_archiving/shared/issue_info.py +++ b/rn_issues_auto_archiving/shared/issue_info.py @@ -19,6 +19,7 @@ class ReopenInfo(TypedDict): introduced_version: str archive_version: str ci_event_type: str + platform_type: str reopen_info: ReopenInfo @@ -47,6 +48,7 @@ class ReopenInfo(): '''值只可能为 open 或 closed''' introduced_version: str archive_version: str - ci_event_type:str + ci_event_type:str + platform_type: str reopen_info: ReopenInfo diff --git a/rn_issues_auto_archiving/shared/log.py b/rn_issues_auto_archiving/shared/log.py index f89ed23..31d3ec8 100644 --- a/rn_issues_auto_archiving/shared/log.py +++ b/rn_issues_auto_archiving/shared/log.py @@ -48,6 +48,8 @@ class Log(): running_ci_by_automated = '''流水线触发触发方式:自动''' http_404_not_found = '''无法请求到对应资源,请检查输入的Issue单号是否正确''' http_status_error = '''HTTP请求返回状态码错误,原因:{reason}''' + issue_type_webhook_detected = '''检测到流水线是由Issue类型webhook触发''' + other_type_webhook_detected = '''检测到流水线是由非Issue类型webhook触发,无需执行归档流程''' job_done = '''脚本执行完毕''' getting_something_success = '''获取 {something} 成功''' @@ -108,4 +110,8 @@ class Log(): not_need_to_push_document = '''本地文件 {file_path} 的sha256值与远程仓库文件 {file_path} 的sha256值一致,跳过推送流程''' need_to_push_document = '''本地文件 {file_path} 的sha256值与远程仓库文件 {file_path} 的sha256值不一致,执行推送流程''' get_local_file_sha256 = '''正在获取本地文件 {file_path} 的sha256值''' - get_local_file_sha256_success = '''成功获取本地文件 {file_path} 的sha256值:{sha256}''' \ No newline at end of file + get_local_file_sha256_success = '''成功获取本地文件 {file_path} 的sha256值:{sha256}''' + + # archiving_success + unknown_platform_type = '''未识别的平台类型 "{platform_type}"''' + send_comment_failed = '''发送评论失败,原因:{exc}''' \ No newline at end of file