forked from ParadiseSS13/Paradise
-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## Что этот PR делает Добавляет воркфлоу, который мержит апстрим. Чейнджлог собирается из обнаруженных в истории ПРов и переводится (опционально). Отслеживаются метки изменений в конфиге, бд, вики. ПРы с этими метками отдельно упоминаются в теле ПРа. Конфликты решать самому, увы. Используется ветка для пула с апстрима, которая может быть создана, если не существует. В чейнджлоге остаются комментарии, содержащие текст исходного изменения, если был перевод, и ссылку на оригинальный ПР. ``` fix: Сброс идентификатора агента больше не вызывает неизменного типа крови. <!-- fix: Resetting an agent ID no longer causes bloodtype to be unchangable. (ParadiseSS13#27509) --> ``` ## Тестирование Пример ПРа (автор я потому что токен был мой): m-dzianishchyts#48 https://github.com/m-dzianishchyts/Paradise-SS220/actions/runs/12247152346/job/34164451774
- Loading branch information
1 parent
3443d5a
commit b78dda5
Showing
5 changed files
with
457 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: Merge Upstream | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
jobs: | ||
merge-upstream: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- id: create_token | ||
uses: actions/create-github-app-token@v1 | ||
with: | ||
app-id: ${{ secrets.APP_ID }} | ||
private-key: ${{ secrets.PRIVATE_KEY }} | ||
|
||
- run: echo "GH_TOKEN=${{ steps.create_token.outputs.token }}" >> "$GITHUB_ENV" | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: 3.x | ||
|
||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install PyGithub googletrans==4.0.0-rc1 | ||
- name: Download the script | ||
run: | | ||
wget https://raw.githubusercontent.com/${{ github.repository }}/${{ github.ref_name }}/tools/changelog/changelog_utils.py | ||
wget https://raw.githubusercontent.com/${{ github.repository }}/${{ github.ref_name }}/tools/merge-upstream/merge_upstream.py | ||
- name: Run the script | ||
env: | ||
GITHUB_TOKEN: ${{ env.GH_TOKEN }} | ||
TARGET_REPO: 'ss220club/Paradise-SS220' | ||
TARGET_BRANCH: 'master' | ||
UPSTREAM_REPO: 'ParadiseSS13/Paradise' | ||
UPSTREAM_BRANCH: 'master' | ||
MERGE_BRANCH: 'merge-upstream' | ||
TRANSLATE_CHANGES: 'true' | ||
CHANGELOG_AUTHOR: 'ParadiseSS13' | ||
run: | | ||
git config --global user.email "[email protected]" | ||
git config --global user.name "Upstream Sync" | ||
python3 merge_upstream.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import re | ||
import copy | ||
|
||
CL_INVALID = ":scroll: CL невалиден" | ||
CL_VALID = ":scroll: CL валиден" | ||
CL_NOT_NEEDED = ":scroll: CL не требуется" | ||
|
||
DISCORD_EMBED_DESCRIPTION_LIMIT = 4096 | ||
|
||
CL_BODY = re.compile(r"(:cl:|🆑)[ \t]*(?P<author>.+?)?\s*\n(?P<content>(.|\n)*?)\n/(:cl:|🆑)", re.MULTILINE) | ||
CL_SPLIT = re.compile(r"\s*(?:(?P<tag>\w+)\s*:)?\s*(?P<message>.*)") | ||
|
||
DISCORD_TAG_EMOJI = { | ||
"soundadd": ":notes:", | ||
"sounddel": ":mute:", | ||
"imageadd": ":frame_photo:", | ||
"imagedel": ":scissors:", | ||
"codeadd": ":sparkles:", | ||
"codedel": ":wastebasket:", | ||
"tweak": ":screwdriver:", | ||
"fix": ":tools:", | ||
"wip": ":construction_site:", | ||
"spellcheck": ":pencil:", | ||
"experiment": ":microscope:" | ||
} | ||
|
||
|
||
def build_changelog(pr: dict, tags_config: dict) -> dict: | ||
changelog = parse_changelog(pr.body, tags_config) | ||
if changelog is None: | ||
raise Exception("Failed to parse the changelog. Check changelog format.") | ||
changelog["author"] = changelog["author"] or pr.user.login | ||
return changelog | ||
|
||
|
||
def emojify_changelog(changelog: dict): | ||
changelog_copy = copy.deepcopy(changelog) | ||
for change in changelog_copy["changes"]: | ||
if change["tag"] in DISCORD_TAG_EMOJI: | ||
change["tag"] = DISCORD_TAG_EMOJI[change["tag"]] | ||
else: | ||
raise Exception(f"Invalid tag for emoji: {change}") | ||
return changelog_copy | ||
|
||
|
||
def validate_changelog(changelog: dict): | ||
if not changelog: | ||
raise Exception("No changelog.") | ||
if not changelog["author"]: | ||
raise Exception("The changelog has no author.") | ||
if len(changelog["changes"]) == 0: | ||
raise Exception("No changes found in the changelog. Use special label if changelog is not expected.") | ||
message = "\n".join(map(lambda change: f"{change['tag']} {change['message']}", changelog["changes"])) | ||
if len(message) > DISCORD_EMBED_DESCRIPTION_LIMIT: | ||
raise Exception(f"The changelog exceeds the length limit ({DISCORD_EMBED_DESCRIPTION_LIMIT}). Shorten it.") | ||
|
||
|
||
def parse_changelog(pr_body: str, tags_config: dict | None = None) -> dict | None: | ||
clean_pr_body = re.sub(r"<!--.*?-->", "", pr_body, flags=re.DOTALL) | ||
cl_parse_result = CL_BODY.search(clean_pr_body) | ||
if cl_parse_result is None: | ||
return None | ||
|
||
cl_changes = [] | ||
for cl_line in cl_parse_result.group("content").splitlines(): | ||
if not cl_line: | ||
continue | ||
change_parse_result = CL_SPLIT.search(cl_line) | ||
if not change_parse_result: | ||
raise Exception(f"Invalid change: '{cl_line}'") | ||
tag = change_parse_result["tag"] | ||
message = change_parse_result["message"] | ||
|
||
if tags_config and tag and tag not in tags_config['tags'].keys(): | ||
raise Exception(f"Invalid tag: '{cl_line}'. Valid tags: {', '.join(tags_config['tags'].keys())}") | ||
if not message: | ||
raise Exception(f"No message for change: '{cl_line}'") | ||
|
||
message = message.strip() | ||
|
||
if tags_config and message in list(tags_config['defaults'].values()): # Check to see if the tags are associated with something that isn't the default text | ||
raise Exception(f"Don't use default message for change: '{cl_line}'") | ||
if tag: | ||
cl_changes.append({ | ||
"tag": tags_config['tags'][tag] if tags_config else tag, | ||
"message": message | ||
}) | ||
# Append line without tag to the previous change | ||
else: | ||
if len(cl_changes): | ||
prev_change = cl_changes[-1] | ||
prev_change["message"] += f" {message}" | ||
else: | ||
raise Exception(f"Change with no tag: {cl_line}") | ||
|
||
if len(cl_changes) == 0: | ||
raise Exception("No changes found in the changelog. Use special label if changelog is not expected.") | ||
return { | ||
"author": str.strip(cl_parse_result.group("author") or "") or None, # I want this to be None, not empty | ||
"changes": cl_changes | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.