forked from AstrBotDevs/AstrBot_Plugins_Collection
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdetect_changed_plugins.py
More file actions
120 lines (90 loc) · 3.58 KB
/
detect_changed_plugins.py
File metadata and controls
120 lines (90 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python3
from __future__ import annotations
import json
import os
import subprocess
import sys
from pathlib import Path
if __package__ in {None, ""}:
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from scripts.validate_plugins.plugins_map import load_plugins_map_text
DEFAULT_ASTRBOT_REF = "master"
ASTRBOT_REMOTE_URL = "https://github.com/AstrBotDevs/AstrBot"
def load_plugins_map(text: str, *, source_name: str) -> dict[str, dict]:
return load_plugins_map_text(text, source_name=source_name)
def detect_changed_plugin_names(*, base: dict[str, dict], head: dict[str, dict]) -> list[str]:
return [name for name, payload in head.items() if base.get(name) != payload]
def fetch_base_ref(base_ref: str) -> None:
subprocess.run(["git", "fetch", "origin", base_ref, "--depth", "1"], check=True)
def read_base_plugins_json(base_ref: str) -> str:
return subprocess.check_output(
["git", "show", f"origin/{base_ref}:plugins.json"],
text=True,
stderr=subprocess.DEVNULL,
)
def resolve_astrbot_ref() -> str:
try:
default_head = subprocess.check_output(
["git", "ls-remote", "--symref", ASTRBOT_REMOTE_URL, "HEAD"],
text=True,
stderr=subprocess.DEVNULL,
)
except subprocess.CalledProcessError:
return DEFAULT_ASTRBOT_REF
for line in default_head.splitlines():
if line.startswith("ref: refs/heads/") and line.endswith("\tHEAD"):
return line.split("refs/heads/", 1)[1].split("\t", 1)[0]
return DEFAULT_ASTRBOT_REF
def detect_pull_request_selection(*, repo_root: Path, base_ref: str) -> dict[str, object]:
try:
fetch_base_ref(base_ref)
base = load_plugins_map(read_base_plugins_json(base_ref), source_name=f"base ref {base_ref}")
except (subprocess.CalledProcessError, ValueError):
base = {}
head_text = (repo_root / "plugins.json").read_text(encoding="utf-8")
try:
head = load_plugins_map(head_text, source_name="PR head")
except ValueError as exc:
raise ValueError(f"plugins.json is invalid on the PR head: {exc}") from exc
changed = detect_changed_plugin_names(base=base, head=head)
validation_note = ""
if not changed:
validation_note = "No plugin entries changed in plugins.json; skipping smoke validation."
return {
"changed": changed,
"should_validate": bool(changed),
"validation_note": validation_note,
}
def write_github_env(
*,
env_path: Path,
astrbot_ref: str,
changed: list[str],
should_validate: bool,
validation_note: str,
) -> None:
with env_path.open("a", encoding="utf-8") as handle:
handle.write(f"ASTRBOT_REF={astrbot_ref}\n")
handle.write(f"PLUGIN_NAME_LIST={','.join(changed)}\n")
handle.write("PLUGIN_LIMIT=\n")
handle.write(f"SHOULD_VALIDATE={'true' if should_validate else 'false'}\n")
handle.write(f"VALIDATION_NOTE={validation_note}\n")
def main() -> int:
base_ref = os.environ["GITHUB_BASE_REF"]
github_env = Path(os.environ["GITHUB_ENV"])
repo_root = Path.cwd()
try:
result = detect_pull_request_selection(repo_root=repo_root, base_ref=base_ref)
except ValueError as exc:
print(str(exc), file=sys.stderr)
return 1
write_github_env(
env_path=github_env,
astrbot_ref=resolve_astrbot_ref(),
changed=result["changed"],
should_validate=result["should_validate"],
validation_note=result["validation_note"],
)
return 0
if __name__ == "__main__":
raise SystemExit(main())