Skip to content

Commit 503f952

Browse files
authored
Add script to update issues like #2993 -> ([#2993](https://..../2993)) (#2993)
## Changes - New command - 'make links' will update references like `#2993` to appropriate markdown link. - New command group - 'make checks' runs all checks that are not fmt/lint or unit test. It is also run on github action. - Modify 'make' to run 'make checks' first, as those are the fastest. ## Why I don't want to spell `([#2993](https://github.com/databricks/cli/pull/2993))` every time in NEXT_CHANGELOG.md
1 parent 9fda88f commit 503f952

File tree

3 files changed

+102
-7
lines changed

3 files changed

+102
-7
lines changed

.github/workflows/push.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,15 @@ jobs:
112112
with:
113113
version: "0.9.1"
114114
args: "format --check"
115-
- name: Run formatting (does not include linting checks)
115+
- name: "make fmt: Python and Go formatting"
116+
# This is already done by actions, but good to check that make command is working
116117
run: |
117118
make fmt
118-
- name: Fail on formatting differences
119+
git diff --exit-code
120+
- name: "make checks: custom checks outside of fmt and lint"
119121
run: |
120-
# Exit with status code 1 if there are differences (i.e. unformatted files)
122+
make checks
121123
git diff --exit-code
122-
- name: Run whitespace check
123-
run: make ws
124124
125125
validate-bundle-schema:
126126
needs: cleanups

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
default: tidy fmt lint ws
1+
default: checks fmt lint
22

33
PACKAGES=./acceptance/... ./libs/... ./internal/... ./cmd/... ./bundle/... .
44

@@ -23,6 +23,12 @@ fmt:
2323
ws:
2424
./tools/validate_whitespace.py
2525

26+
links:
27+
./tools/update_github_links.py
28+
29+
# Checks other than 'fmt' and 'lint'; these are fast, so can be run first
30+
checks: tidy ws links
31+
2632
test:
2733
${GOTESTSUM_CMD} -- ${PACKAGES}
2834

@@ -72,4 +78,4 @@ generate:
7278
[ ! -f .github/workflows/next-changelog.yml ] || rm .github/workflows/next-changelog.yml
7379
pushd experimental/python && make codegen
7480

75-
.PHONY: lint tidy lintcheck fmt test cover showcover build snapshot schema integration integration-short acc-cover acc-showcover docs ws
81+
.PHONY: lint tidy lintcheck fmt test cover showcover build snapshot schema integration integration-short acc-cover acc-showcover docs ws links checks

tools/update_github_links.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#!/usr/bin/env python3
2+
"""Update PR references in changelog files.
3+
4+
1. Convert occurrences of `#1234` to the canonical markdown link
5+
`([#1234](https://github.com/databricks/cli/pull/1234))`.
6+
2. Validate that for existing converted references the PR number in the text
7+
and in the URL match.
8+
"""
9+
10+
import argparse
11+
import pathlib
12+
import re
13+
import sys
14+
15+
DEFAULT_FILES = ("NEXT_CHANGELOG.md", "CHANGELOG.md")
16+
17+
# Regex that matches an *already converted* link, e.g.:
18+
# ([#1234](https://github.com/databricks/cli/pull/1234))
19+
# The groups capture the PR number in the text and in the URL respectively so
20+
# they can be compared for consistency.
21+
CONVERTED_LINK_RE = re.compile(
22+
r"\(\[#(?P<num_text>\d+)\]\(" # ([#1234](
23+
r"https://github\.com/databricks/cli/pull/(?P<num_url>\d+)" # …/pull/1234
24+
r"\)\)" # ))
25+
)
26+
27+
# Regex that matches a *raw* reference, `#1234`, that is **not** already inside
28+
# a converted link. The negative look-behind ensures the # is not preceded by
29+
# a literal '[' which would indicate an already converted link.
30+
RAW_REF_RE = re.compile(r"(?<!\[)#(?P<num>\d+)\b")
31+
32+
33+
def find_mismatched_links(text):
34+
"""Return texts of mismatching converted links."""
35+
mismatches = []
36+
for m in CONVERTED_LINK_RE.finditer(text):
37+
num_text, num_url = m.group("num_text"), m.group("num_url")
38+
if num_text != num_url:
39+
context = text[max(0, m.start() - 20) : m.end() + 20]
40+
mismatches.append(f"Converted link numbers differ: text #{num_text} vs URL #{num_url} — …{context}…")
41+
return mismatches
42+
43+
44+
def convert_raw_references(text):
45+
"""Convert raw `#1234` references to markdown links."""
46+
47+
def _repl(match):
48+
num = match.group("num")
49+
return f"([#{num}](https://github.com/databricks/cli/pull/{num}))"
50+
51+
return RAW_REF_RE.sub(_repl, text)
52+
53+
54+
def process_file(path):
55+
"""Process a single file.
56+
57+
Returns True if the file was *modified*.
58+
Raises `SystemExit` with non-zero status on mismatching converted links.
59+
"""
60+
original = path.read_text(encoding="utf-8")
61+
62+
mismatches = find_mismatched_links(original)
63+
if mismatches:
64+
for msg in mismatches:
65+
print(f"{path}:{msg}", file=sys.stderr)
66+
sys.exit(1)
67+
68+
updated = convert_raw_references(original)
69+
if updated != original:
70+
path.write_text(updated, encoding="utf-8")
71+
print(f"Updated {path}")
72+
return True
73+
74+
return False
75+
76+
77+
def main(argv=None):
78+
parser = argparse.ArgumentParser(description="Convert #PR references in changelogs to links.")
79+
parser.add_argument("files", nargs="*", help=f"Markdown files to process (default: {DEFAULT_FILES})")
80+
args = parser.parse_args(argv)
81+
82+
modified_any = False
83+
for file_path in args.files or DEFAULT_FILES:
84+
file_path = pathlib.Path(file_path)
85+
modified_any |= process_file(file_path)
86+
87+
88+
if __name__ == "__main__":
89+
main()

0 commit comments

Comments
 (0)