Skip to content

Commit 83cb9e8

Browse files
Releaser: fix release untagging, include root repo changes, filter commitlint messages (#220)
* Releaser update: fix release untagging, include root repo changes, filter commitlint messages * add commitlint re for title filtering
1 parent a8ebc46 commit 83cb9e8

File tree

4 files changed

+62
-33
lines changed

4 files changed

+62
-33
lines changed

.github/workflows/scripts/changelog/changelog_config.json

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
{
22
"repositories": [
3+
{
4+
"name": "datalens",
5+
"url": "https://github.com/datalens-tech/datalens"
6+
},
37
{
48
"name": "datalens-ui",
59
"url": "https://github.com/datalens-tech/datalens-ui",
@@ -36,6 +40,7 @@
3640
}
3741
],
3842
"changelog_include_label": "changelog",
43+
"include_root_repo_changes": true,
3944
"images_versions_section": "Image versions",
4045
"other_changes_section": "Other",
4146
"single_section_title": "Changes",

.github/workflows/scripts/changelog/clone_repos.sh

100644100755
File mode changed.

.github/workflows/scripts/changelog/releaser.py

+51-30
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,17 @@ def li(text: str) -> str:
5454

5555
@staticmethod
5656
def clean_pr_title(title: str) -> str:
57+
task_re = r"[a-zA-Z]+-\d+" # task tracker issue key
5758
prefix_patterns_to_remove = [
58-
r"^\[?(DLPROJECTS|CHARTS|BI|YCDOCS|DOCSUP)-\d+\]?[ .:]*",
59+
rf"^\[?({task_re})\]?[ .:]*", # e.g. "TASK-123: minor improvements"
60+
rf"^[a-z]+(\([a-z, ]+\))?: {task_re} ", # e.g. "fix(datasets, connectors): TASK-123 moderate improvements"
61+
rf"^[a-z]+(\([a-z, ]+\))?: ", # e.g. "fix(datasets, connectors): major improvements"
5962
]
6063

6164
for pattern in prefix_patterns_to_remove:
6265
title = re.sub(pattern, "", title)
6366
title = title.strip(" .")
67+
title = title[0].upper() + title[1:]
6468

6569
return title
6670

@@ -100,7 +104,7 @@ def release_bump_version(version: str, release_type: str) -> str:
100104
def normalize_tag(tag: str) -> str:
101105
""" Ensures there is a "v" at the beginning """
102106

103-
return "v" + tag.lstrip("v")
107+
return "v" + tag.lstrip("v") if tag else ""
104108

105109

106110
def normalize_version(version: str) -> str:
@@ -123,25 +127,29 @@ def write_output(content: str) -> None:
123127

124128
def populate_helper_maps(
125129
changelog_config: dict[str, Any],
126-
current_image_versions: dict[str, str],
130+
current_repo_versions: dict[str, str],
127131
new_repo_versions: dict[str, str],
128132
) -> None:
129133
for repo in changelog_config["repositories"]:
130-
for img in repo["images"]:
134+
for img in repo.get("images", []):
131135
REPO_CFG_BY_IMG[img["name"]] = repo
132-
IMG_VERSIONS_BY_NAME[img["name"]]["from"] = current_image_versions[img["version_descriptor"]]
136+
IMG_VERSIONS_BY_NAME[img["name"]]["from"] = current_repo_versions[img["version_descriptor"]]
133137

134138
for repo in changelog_config["repositories"]:
135-
for img in repo["images"]:
139+
repo_images = repo.get("images", [])
140+
for img in repo_images:
136141
existing_tag = REPO_VERSIONS.get(repo["name"], {}).get("from")
137-
new_tag = current_image_versions[img["version_descriptor"]]
142+
new_tag = current_repo_versions[img["version_descriptor"]]
138143
if existing_tag:
139144
new_tag = min(new_tag, existing_tag)
140145
LOGGER.info(
141146
f"Got multiple image tags for {img['name']}, "
142147
f"picking the older one for the starting version ({new_tag})"
143148
)
144149
REPO_VERSIONS[repo["name"]]["from"] = new_tag
150+
if not repo_images:
151+
# if the repo provides no images, its version should be described by its name
152+
REPO_VERSIONS[repo["name"]]["from"] = current_repo_versions.get(repo["name"], "")
145153

146154
for repo_name, new_version in new_repo_versions.items():
147155
REPO_VERSIONS[repo_name]["to"] = new_version
@@ -156,7 +164,7 @@ def populate_helper_maps(
156164
}
157165

158166
# save result image to map
159-
repo_images = next(repo["images"] for repo in changelog_config["repositories"] if repo["name"] == repo_name)
167+
repo_images = next(repo.get("images", []) for repo in changelog_config["repositories"] if repo["name"] == repo_name)
160168
for img in repo_images:
161169
IMG_VERSIONS_BY_NAME[img["name"]]["to"] = normalize_version(REPO_VERSIONS[repo_name]["to"])
162170

@@ -170,15 +178,19 @@ def gather_changelog(cfg: dict[str, Any], repos_dir: Path, gh_headers: dict[str,
170178
for repository in cfg["repositories"]:
171179
repo_full_name = "/".join(repository["url"].split("/")[-2:])
172180

181+
tag_from = REPO_VERSIONS[repository["name"]]["from"]
182+
tag_to = REPO_VERSIONS[repository["name"]]["to"]
173183
commits = gh.get_commits_between_tags(
174-
tag_from=REPO_VERSIONS[repository["name"]]["from"],
175-
tag_to=REPO_VERSIONS[repository["name"]]["to"],
184+
tag_from=tag_from,
185+
tag_to=tag_to,
176186
repo_path=repos_dir / repository["name"],
177187
)
188+
LOGGER.info(f"Got {len(commits)} commits from range {tag_from}..{tag_to} for {repo_full_name}")
178189

179-
for commit in commits:
190+
for idx, commit in enumerate(commits):
191+
LOGGER.info(f"[{idx + 1}/{len(commits)}] Fetching PRs for commit {commit.sha}")
180192
prs_info = gh.get_pull_requests_by_commit(
181-
repo_full_name, commit, gh_headers, changelog_config['changelog_include_label']
193+
repo_full_name, commit, gh_headers, changelog_config["changelog_include_label"]
182194
)
183195

184196
for pr in prs_info:
@@ -223,7 +235,7 @@ def gather_changelog(cfg: dict[str, Any], repos_dir: Path, gh_headers: dict[str,
223235
parser.add_argument("--root-repo-name", default="datalens-tech/datalens")
224236
parser.add_argument("--repos-dir", type=Path, default=Path("./repos"))
225237
parser.add_argument("--changelog-path", type=Path, default=Path("../../../../CHANGELOG.md"))
226-
parser.add_argument("--version-config-path", required=True, type=Path, help="path to versionn_config.json")
238+
parser.add_argument("--version-config-path", required=True, type=Path, help="path to versions-config.json")
227239
parser.add_argument("--release-type", choices=("major", "minor", "patch"), default="minor")
228240
parser.add_argument("--new-repo-versions", required=True, help=(
229241
'a new version for each repo, space separated in the format "name:tag",'
@@ -247,20 +259,29 @@ def gather_changelog(cfg: dict[str, Any], repos_dir: Path, gh_headers: dict[str,
247259
changelog_config: dict[str, Any] = json.load(f)
248260

249261
with open(args.version_config_path, "r") as f:
250-
current_image_versions: dict[str, str] = json.load(f)
262+
current_repo_versions: dict[str, str] = json.load(f)
251263

264+
new_repo_versions_input = args.new_repo_versions.strip()
252265
new_repo_versions: dict[str, str] = {}
253-
for item in args.new_repo_versions.strip().split(" "):
254-
repo_name, new_version = item.split(":")
255-
new_repo_versions[repo_name] = normalize_version(new_version)
266+
if new_repo_versions_input:
267+
for item in new_repo_versions_input.split(" "):
268+
repo_name, new_version = item.split(":")
269+
new_repo_versions[repo_name] = normalize_version(new_version)
270+
271+
# Figure out release tags
272+
gh_auth_headers = gh.make_gh_auth_headers_from_env()
273+
root_repo_name_full = args.root_repo_name
274+
root_repo_name_short = root_repo_name_full.split("/")[-1]
275+
latest_release = gh.get_latest_repo_release(root_repo_name_full, gh_auth_headers)
276+
new_release = release_bump_version(latest_release, args.release_type)
256277

257278
# Prepare helper mappings
258-
populate_helper_maps(changelog_config, current_image_versions, new_repo_versions)
279+
if changelog_config.get("include_root_repo_changes", True):
280+
current_repo_versions[root_repo_name_short] = latest_release
281+
new_repo_versions[root_repo_name_short] = ""
282+
populate_helper_maps(changelog_config, current_repo_versions, new_repo_versions)
259283

260284
# Gather changes
261-
gh_auth_headers = gh.make_gh_auth_headers_from_env()
262-
latest_release = gh.get_latest_repo_release(args.root_repo_name, gh_auth_headers)
263-
new_release = release_bump_version(latest_release, args.release_type)
264285
CF = ChangelogFormatter
265286
changelog = gather_changelog(changelog_config, args.repos_dir, gh_auth_headers)
266287

@@ -270,18 +291,18 @@ def gather_changelog(cfg: dict[str, Any], repos_dir: Path, gh_headers: dict[str,
270291

271292
changelog_lines.append(CF.release(new_release) + f" ({datetime.date.today()})")
272293

273-
changelog_lines.append(CF.section(changelog_config['images_versions_section']))
294+
changelog_lines.append(CF.section(changelog_config["images_versions_section"]))
274295
img_versions_list: list[str] = []
275296
for img_name, img_versions in IMG_VERSIONS_BY_NAME.items():
276297
if img_versions["from"] != img_versions["to"]:
277298
full_changelog_url = "{repo_url}/compare/v{v_from}...v{v_to}".format(
278-
repo_url=REPO_CFG_BY_IMG[img_name]['url'],
279-
v_from=img_versions['from'],
280-
v_to=img_versions['to'],
299+
repo_url=REPO_CFG_BY_IMG[img_name]["url"],
300+
v_from=img_versions["from"],
301+
v_to=img_versions["to"],
281302
)
282-
img_versions_list.append(CF.img_version_changed(img_name, img_versions['from'], img_versions['to'], full_changelog_url))
303+
img_versions_list.append(CF.img_version_changed(img_name, img_versions["from"], img_versions["to"], full_changelog_url))
283304
else:
284-
img_versions_list.append(CF.img_version_unchanged(img_name, img_versions['to']))
305+
img_versions_list.append(CF.img_version_unchanged(img_name, img_versions["to"]))
285306
changelog_lines.extend(sorted(img_versions_list)) # let's have them in a predictable order
286307

287308
for changelog_section, section_lines in sorted(changelog.items()): # type: str, list[tuple[str, str]]
@@ -306,7 +327,7 @@ def gather_changelog(cfg: dict[str, Any], repos_dir: Path, gh_headers: dict[str,
306327
# Update image versions
307328
new_image_versions: dict[str, str] = {}
308329
for repo in changelog_config["repositories"]:
309-
for img in repo["images"]:
330+
for img in repo.get("images", []):
310331
new_image_versions[img["version_descriptor"]] = IMG_VERSIONS_BY_NAME[img["name"]]["to"]
311332
if not dry_run:
312333
with open(args.version_config_path, "w") as f:
@@ -317,7 +338,7 @@ def gather_changelog(cfg: dict[str, Any], repos_dir: Path, gh_headers: dict[str,
317338
# Create GitHub release
318339
if args.create_release and not dry_run:
319340
release_resp = requests.post(
320-
f"https://api.github.com/repos/{args.root_repo_name}/releases",
341+
f"https://api.github.com/repos/{root_repo_name_full}/releases",
321342
headers=gh_auth_headers,
322343
json=dict(
323344
tag_name=new_release,
@@ -331,7 +352,7 @@ def gather_changelog(cfg: dict[str, Any], repos_dir: Path, gh_headers: dict[str,
331352
)
332353
release_resp.raise_for_status()
333354
resp_body = release_resp.json()
334-
release_url = resp_body.get('html_url')
355+
release_url = resp_body.get("html_url")
335356
print(f"Release response body: {resp_body}")
336357
print(f"Successfully created a release: {release_url}")
337358
if args.make_outputs:

.github/workflows/scripts/changelog/update_release.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,20 @@
88
import github_helpers as gh
99

1010

11-
def update_release_body(repo_full_name: str, headers: dict[str, str], release_id: str, new_body: str) -> str:
11+
def update_release_body(repo_full_name: str, headers: dict[str, str], release_tag: str, new_body: str) -> str:
1212
""" Updates the release description with the passed content, returns release url """
1313

14+
release_id = gh.find_release_by_tag(args.root_repo_name, gh_auth_headers, release_tag)
15+
1416
release_resp = gh.request_with_retries(
1517
functools.partial(
1618
requests.patch,
1719
url=f"https://api.github.com/repos/{repo_full_name}/releases/{release_id}",
1820
headers=headers,
1921
json=dict(
2022
body=new_body,
23+
tag_name=release_tag,
24+
draft=True,
2125
),
2226
)
2327
)
@@ -42,6 +46,5 @@ def update_release_body(repo_full_name: str, headers: dict[str, str], release_id
4246
new_line = f.readline()
4347

4448
gh_auth_headers = gh.make_gh_auth_headers_from_env()
45-
release_to_update = gh.find_release_by_tag(args.root_repo_name, gh_auth_headers, release_tag)
46-
release_url = update_release_body(args.root_repo_name, gh_auth_headers, release_to_update, changelog_body)
49+
release_url = update_release_body(args.root_repo_name, gh_auth_headers, release_tag, changelog_body)
4750
print("Successfully updated release:", release_url)

0 commit comments

Comments
 (0)