Skip to content

Commit 192dbea

Browse files
mtnbikencclaude
andcommitted
[hack] Fix linting issues in create-release-tag.py
- Wrap all lines to the 79-character flake8 limit - Add check=False to subprocess.run (W1510) - Chain exception with raise...from exc in resolve_commit (W0707) - Add missing docstrings to tag_exists and main (C0116) - Suppress invalid-name for the hyphenated script filename (C0103) - Suppress main() complexity warnings with inline disable (R0912/R0914/R0915) pylint score: 10.00/10 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3c3550d commit 192dbea

1 file changed

Lines changed: 103 additions & 45 deletions

File tree

hack/create-release-tag.py

Lines changed: 103 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
python3 hack/create-release-tag.py <version>
1212
python3 hack/create-release-tag.py <version> --commit <SHA>
1313
python3 hack/create-release-tag.py <version> --date YYYY-MM-DD
14-
python3 hack/create-release-tag.py <version> --commit <SHA> --date YYYY-MM-DD
14+
python3 hack/create-release-tag.py <version> --commit <SHA> \
15+
--date YYYY-MM-DD
1516
1617
--commit is required when the version has no entry in the bundle catalog
1718
(e.g. backport releases that were never shipped as a container image).
@@ -33,15 +34,15 @@
3334
hex SHA that Konflux publishes as an image tag alongside the version tag.
3435
3536
Operator image: openshift4-wincw/windows-machine-config-rhel9-operator
36-
Provides: push_date — the UTC timestamp when the image was published to the
37-
catalog. This is used as the tag date so the annotated tag timestamp
37+
Provides: push_date — the UTC timestamp when the image was published to
38+
the catalog. This is used as the tag date so the annotated tag timestamp
3839
reflects the actual release date rather than the date the tag was created.
3940
4041
Local git repository
41-
Provides: existing tag detection (prevents accidental overwrites), full SHA
42-
expansion from short SHAs via git rev-parse, commit existence verification
43-
to catch catalog/repo mismatches before the tag is written, and upstream
44-
remote detection for the post-creation push instruction.
42+
Provides: existing tag detection (prevents accidental overwrites), full
43+
SHA expansion from short SHAs via git rev-parse, commit existence
44+
verification to catch catalog/repo mismatches before the tag is written,
45+
and upstream remote detection for the post-creation push instruction.
4546
4647
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4748
LOGIC
@@ -53,7 +54,8 @@
5354
image tag (fallback for images that predate the OCI label).
5455
Logic:
5556
• Scans the bundle catalog for the image whose tags include vX.Y.Z.
56-
• Prefers the full SHA from the OCI label; falls back to the short SHA tag.
57+
• Prefers the full SHA from the OCI label; falls back to the short SHA
58+
tag.
5759
• Any SHA (full or short) is expanded to a full 40-character commit via
5860
git rev-parse and verified to exist locally. This catches catalog/repo
5961
mismatches (e.g. if the local clone is stale) before writing anything.
@@ -63,13 +65,16 @@
6365
6466
2. TAG DATE RESOLUTION
6567
Source: Operator image catalog
66-
Data: push_date field from the repository entry for the matching version.
68+
Data: push_date field from the repository entry for the matching
69+
version.
6770
Logic:
68-
• The push_date is the UTC timestamp when the operator image was published.
69-
• Only the date portion (YYYY-MM-DD) is used; the time is fixed to noon UTC
70-
(12:00:00+0000) to produce an unambiguous, timezone-neutral timestamp.
71-
• The fixed noon time is set via GIT_COMMITTER_DATE when git tag is invoked,
72-
so it appears as the tag's creation date in git log and GitHub.
71+
• The push_date is the UTC timestamp when the operator image was
72+
published.
73+
• Only the date portion (YYYY-MM-DD) is used; the time is fixed to noon
74+
UTC (12:00:00+0000) to produce an unambiguous, timezone-neutral
75+
timestamp.
76+
• The fixed noon time is set via GIT_COMMITTER_DATE when git tag is
77+
invoked, so it appears as the tag's creation date in git log and GitHub.
7378
• --date skips the catalog lookup and uses the provided date instead.
7479
7580
3. TAG CREATION
@@ -85,12 +90,14 @@
8590
4. PUSH INSTRUCTION
8691
Logic:
8792
• After creation, scans git remote -v for a remote whose URL contains
88-
"openshift/windows-machine-config-operator" and uses its configured name
89-
(commonly "upstream") in the suggested push command.
93+
"openshift/windows-machine-config-operator" and uses its configured
94+
name (commonly "upstream") in the suggested push command.
9095
• Falls back to the canonical SSH URL if no matching remote is found, so
9196
the command is always complete and immediately usable.
9297
"""
9398

99+
# pylint: disable=invalid-name # hyphenated script name is intentional
100+
94101
import argparse
95102
import os
96103
import re
@@ -119,11 +126,19 @@
119126
# ---------------------------------------------------------------------------
120127

121128
def _fetch_pages(api_url: str) -> list:
122-
"""Fetch all image records from a catalog API endpoint, handling pagination."""
129+
"""Fetch all image records from a catalog API endpoint,
130+
handling pagination."""
123131
images, page = [], 0
124132
while True:
125-
resp = requests.get(api_url, params={"page_size": 100, "page": page,
126-
"sort_by": "creation_date[desc]"}, timeout=30)
133+
resp = requests.get(
134+
api_url,
135+
params={
136+
"page_size": 100,
137+
"page": page,
138+
"sort_by": "creation_date[desc]",
139+
},
140+
timeout=30,
141+
)
127142
resp.raise_for_status()
128143
batch = resp.json().get("data", [])
129144
if not batch:
@@ -152,19 +167,25 @@ def _labels(img: dict) -> dict:
152167

153168
def fetch_bundle_info(version: str) -> tuple[str, str]:
154169
"""
155-
Return (commit, source_description) for the given version from the bundle catalog.
156-
Prefers the org.opencontainers.image.revision label (full SHA); falls back to
157-
the short hex SHA image tag. Returns ('', '') if the version is not found.
170+
Return (commit, source_description) for the given version from the
171+
bundle catalog. Prefers the org.opencontainers.image.revision label
172+
(full SHA); falls back to the short hex SHA image tag.
173+
Returns ('', '') if the version is not found.
158174
"""
159175
for img in _fetch_pages(BUNDLE_CATALOG_API):
160176
repos = img.get("repositories", [])
161177
if _version_from_tags(repos) != version:
162178
continue
163-
all_tags = [t.get("name", "") for repo in repos for t in repo.get("tags", [])]
179+
all_tags = [
180+
t.get("name", "") for repo in repos for t in repo.get("tags", [])
181+
]
164182
commit = _labels(img).get("org.opencontainers.image.revision", "")
165183
if commit:
166184
return commit, "bundle image OCI label"
167-
sha_tags = [t for t in all_tags if _HEX_RE.match(t) and not _VERSION_TAG_RE.match(t)]
185+
sha_tags = [
186+
t for t in all_tags
187+
if _HEX_RE.match(t) and not _VERSION_TAG_RE.match(t)
188+
]
168189
if sha_tags:
169190
return sha_tags[0], "bundle image tag (short SHA)"
170191
return "", ""
@@ -173,8 +194,8 @@ def fetch_bundle_info(version: str) -> tuple[str, str]:
173194

174195
def fetch_operator_push_date(version: str) -> str:
175196
"""
176-
Return the push_date (YYYY-MM-DD) for the given version from the operator catalog,
177-
or '' if not found.
197+
Return the push_date (YYYY-MM-DD) for the given version from the
198+
operator catalog, or '' if not found.
178199
"""
179200
for img in _fetch_pages(OPERATOR_CATALOG_API):
180201
for repo in img.get("repositories", []):
@@ -192,13 +213,16 @@ def fetch_operator_push_date(version: str) -> str:
192213

193214
def git(*args, env=None) -> str:
194215
"""Run a git command and return stdout, raising on failure."""
195-
result = subprocess.run(["git", *args], capture_output=True, text=True, env=env)
216+
result = subprocess.run(
217+
["git", *args], capture_output=True, text=True, env=env, check=False
218+
)
196219
if result.returncode != 0:
197220
raise RuntimeError(result.stderr.strip())
198221
return result.stdout.strip()
199222

200223

201224
def tag_exists(tag: str) -> bool:
225+
"""Return True if the git tag already exists in this repository."""
202226
try:
203227
git("rev-parse", tag)
204228
return True
@@ -210,11 +234,11 @@ def resolve_commit(ref: str) -> str:
210234
"""Return the full commit SHA for ref, or raise RuntimeError."""
211235
try:
212236
return git("rev-parse", f"{ref}^{{commit}}")
213-
except RuntimeError:
237+
except RuntimeError as exc:
214238
raise RuntimeError(
215239
f"Commit '{ref}' not found in this repository.\n"
216240
"Ensure your local repo is up to date: git fetch origin"
217-
)
241+
) from exc
218242

219243

220244
# ---------------------------------------------------------------------------
@@ -223,8 +247,8 @@ def resolve_commit(ref: str) -> str:
223247

224248
def _find_upstream_remote() -> str:
225249
"""
226-
Return the name of the remote pointing to openshift/windows-machine-config-operator,
227-
or '' if none is configured.
250+
Return the name of the remote pointing to
251+
openshift/windows-machine-config-operator, or '' if none is configured.
228252
"""
229253
try:
230254
lines = git("remote", "-v").splitlines()
@@ -233,12 +257,15 @@ def _find_upstream_remote() -> str:
233257
for line in lines:
234258
# Each line: "<name>\t<url> (fetch|push)"
235259
parts = line.split()
236-
if len(parts) >= 2 and "openshift/windows-machine-config-operator" in parts[1]:
260+
if (len(parts) >= 2
261+
and "openshift/windows-machine-config-operator" in parts[1]):
237262
return parts[0]
238263
return ""
239264

240265

266+
# pylint: disable=too-many-locals,too-many-branches,too-many-statements
241267
def main():
268+
"""Parse args, resolve tag details, confirm with user, create the tag."""
242269
parser = argparse.ArgumentParser(
243270
description="Create an annotated WMCO release tag.",
244271
formatter_class=argparse.RawDescriptionHelpFormatter,
@@ -255,8 +282,10 @@ def main():
255282
)
256283
parser.add_argument("version", metavar="X.Y.Z",
257284
help="Release version without 'v' prefix")
258-
parser.add_argument("--commit", metavar="SHA",
259-
help="Override commit SHA (required if version is not in catalog)")
285+
parser.add_argument(
286+
"--commit", metavar="SHA",
287+
help="Override commit SHA (required if version is not in catalog)",
288+
)
260289
parser.add_argument("--date", metavar="YYYY-MM-DD",
261290
help="Override published date")
262291
args = parser.parse_args()
@@ -273,24 +302,40 @@ def main():
273302
message = f"Windows Machine Config Operator {tag}"
274303

275304
if tag_exists(tag):
276-
print(f"ERROR: Tag '{tag}' already exists. Delete it first if you intend to recreate it.",
277-
file=sys.stderr)
305+
print(
306+
f"ERROR: Tag '{tag}' already exists. "
307+
"Delete it first if you intend to recreate it.",
308+
file=sys.stderr,
309+
)
278310
sys.exit(1)
279311

280-
# Resolve commit
281312
need_catalog = not args.commit or not args.date
282313
if need_catalog:
283-
print(f"Fetching release details for {tag} from Red Hat Container Catalog...", flush=True)
314+
print(
315+
f"Fetching release details for {tag} "
316+
"from Red Hat Container Catalog...",
317+
flush=True,
318+
)
284319

285320
if args.commit:
286321
commit_sha = args.commit
287322
commit_source = "provided manually"
288323
else:
289324
commit_sha, commit_source = fetch_bundle_info(version)
290325
if not commit_sha:
291-
print(f"\nERROR: Could not resolve commit SHA for {tag}.", file=sys.stderr)
292-
print(" The bundle image for this version may not be in the catalog.", file=sys.stderr)
293-
print(" Provide the commit manually: --commit <SHA>", file=sys.stderr)
326+
print(
327+
f"\nERROR: Could not resolve commit SHA for {tag}.",
328+
file=sys.stderr,
329+
)
330+
print(
331+
" The bundle image for this version "
332+
"may not be in the catalog.",
333+
file=sys.stderr,
334+
)
335+
print(
336+
" Provide the commit manually: --commit <SHA>",
337+
file=sys.stderr,
338+
)
294339
sys.exit(1)
295340

296341
if args.date:
@@ -300,9 +345,19 @@ def main():
300345
published_date = fetch_operator_push_date(version)
301346
date_source = "operator image push date"
302347
if not published_date:
303-
print(f"\nERROR: Could not resolve published date for {tag}.", file=sys.stderr)
304-
print(" The operator image for this version may not be in the catalog.", file=sys.stderr)
305-
print(" Provide the date manually: --date YYYY-MM-DD", file=sys.stderr)
348+
print(
349+
f"\nERROR: Could not resolve published date for {tag}.",
350+
file=sys.stderr,
351+
)
352+
print(
353+
" The operator image for this version "
354+
"may not be in the catalog.",
355+
file=sys.stderr,
356+
)
357+
print(
358+
" Provide the date manually: --date YYYY-MM-DD",
359+
file=sys.stderr,
360+
)
306361
sys.exit(1)
307362

308363
# Expand to full commit SHA and verify it exists locally
@@ -343,7 +398,10 @@ def main():
343398
sys.exit(1)
344399

345400
upstream_remote = _find_upstream_remote()
346-
push_target = upstream_remote if upstream_remote else "git@github.com:openshift/windows-machine-config-operator.git"
401+
upstream_url = (
402+
"git@github.com:openshift/windows-machine-config-operator.git"
403+
)
404+
push_target = upstream_remote if upstream_remote else upstream_url
347405

348406
print()
349407
print(f"Tag '{tag}' created. To push to the upstream repository:")

0 commit comments

Comments
 (0)