-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathprepare_pr.py
executable file
·126 lines (103 loc) · 4.59 KB
/
prepare_pr.py
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
121
122
123
124
125
126
#!/usr/bin/env python3
#############################################################################
##
## This file is part of GAP, a system for computational discrete algebra.
##
## Copyright of GAP belongs to its developers, whose names are too numerous
## to list here. Please refer to the COPYRIGHT file for details.
##
## SPDX-License-Identifier: GPL-2.0-or-later
##
"""
This script takes the name of a single package or package group (as defined in
`group_packages.py`), followed by a list of paths to modified meta.json files.
It selects from the given list of modified meta.json files all that correspond
to the given package or group, and finally prints a list of environment
variable definitions suitable for addittion to the $GITHUB_ENV files used in
GitHub workflows to define environment variables. The data in these
definitions is used to set up a pull request by the `scan-for-updates.yml`
GitHub workflow.
"""
import random
import string
import subprocess
import sys
from typing import Any, Dict, List
import group_packages
import utils
def randomword(length: int) -> str:
letters = string.ascii_lowercase
return "".join(random.choice(letters) for i in range(length))
def infostr_for_package(pkg_json: Dict[str, Any]) -> str:
s = f"- {pkg_json['PackageName']} {pkg_json['Version']}: "
s += f"[[`PackageInfo.g`]({pkg_json['PackageInfoURL']})] "
s += f"[[`README`]({pkg_json['README_URL']})] "
s += f"[[website]({pkg_json['PackageWWWHome']})] "
s += f"[[source archive]({utils.archive_url(pkg_json)})] "
s += "\n"
return s
def is_new_package(pkg_name: str) -> bool:
fname = utils.metadata_fname(pkg_name)
result = subprocess.run(
["git", "status", "--porcelain", fname], capture_output=True, encoding="UTF-8"
)
if result.returncode != 0:
utils.error("git status returned an error")
return result.stdout.startswith("?")
def main(pkg_or_group_name: str, modmap: List[str]) -> None:
# select all entries of `modified` in the given group
modified = [
x for x in modmap if group_packages.name_or_group(x) == pkg_or_group_name
]
if len(modified) == 0:
utils.error(f"no modified files belong to {pkg_or_group_name}")
# get the metadata for the first package; if it is the only one,
# we'll use it to get the version for the PR title; if it is one
# of multiple in a group, we can still use it to extract the common
# source repository URL
pkg_json = utils.metadata(modified[0])
# generate PR title and secondary label
label = "package update"
title = f"[{pkg_or_group_name}] "
if len(modified) == 1:
version = pkg_json["Version"]
if is_new_package(modified[0]):
title += f"New package, version {version}"
label = "new package"
else:
if group_packages.is_group(pkg_or_group_name):
title += f"Update {pkg_json['PackageName']} to {version}"
else:
title += f"Update to {version}"
label = "package update"
else:
title += "Updates for several packages"
print(f"PR_TITLE={title}")
print(f"PR_LABEL={label}")
# list of files to be included into the PR, comma-separated, for the
# 'add-paths' input of the create-pull-request action; see
# https://github.com/peter-evans/create-pull-request#action-inputs
files = map(utils.metadata_fname, modified)
print(f"PR_FILES={','.join(files)}")
# generate PR body content
mod_json = map(utils.metadata, modified)
body = "".join(map(infostr_for_package, mod_json))
# add link to the source repository; we do this only once, as package groups
# are defined via the source repository
if "SourceRepository" in pkg_json:
url = pkg_json["SourceRepository"]["URL"]
body += f"""- [source repository]({url})""" + "\n"
# HACK: also add the issue tracker only once; while in theory packages in
# a group could have different issue trackers, this is not currently the case,
# ever. We'll deal with it if it ever happens
if "IssueTrackerURL" in pkg_json:
body += f"""- [issue tracker]({pkg_json["IssueTrackerURL"]})""" + "\n"
# generate multiline environment variable using "heredoc" syntax, as per
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
# we use a random delimiter for security reasons, to avoid injection attacks
delim = randomword(10)
print(f"PR_BODY<<{delim}")
print(body)
print(delim)
if __name__ == "__main__":
main(sys.argv[1], [utils.normalize_pkg_name(x) for x in sys.argv[2:]])