Skip to content

Commit 71b4882

Browse files
committed
Merge branch 'main' into semver-support
2 parents 5f87607 + 5126dc7 commit 71b4882

File tree

3 files changed

+220
-4
lines changed

3 files changed

+220
-4
lines changed

src/gardenlinux/github/release_notes/sections.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,162 @@ def release_notes_image_ids_section(metadata_files):
300300
output += "\n</details>\n\n"
301301

302302
return output
303+
304+
305+
def generate_table_format(grouped_data):
306+
"""
307+
Generate the table format with collapsible region details
308+
"""
309+
output = "| Variant | Platform | Architecture | Flavor | Regions & Image IDs | Download Links |\n"
310+
output += "|---------|----------|--------------|--------|---------------------|----------------|\n"
311+
312+
for variant in IMAGE_IDS_VARIANT_ORDER:
313+
if variant not in grouped_data:
314+
continue
315+
316+
for platform in sorted(grouped_data[variant].keys()):
317+
for arch in sorted(grouped_data[variant][platform].keys()):
318+
for metadata in grouped_data[variant][platform][arch]:
319+
data = PLATFORMS[platform].published_images_by_regions(metadata)
320+
if data is None:
321+
continue
322+
323+
details_content = PLATFORMS[platform].region_details(metadata)
324+
summary_text = PLATFORMS[platform].summary_text(metadata)
325+
326+
download_link = PLATFORMS[platform].artifact_for_flavor(data['flavor'])
327+
328+
variant_display = IMAGE_IDS_VARIANT_TABLE_NAMES[variant]
329+
output += (f"| {variant_display} "
330+
f"| {PLATFORMS[platform].full_name()} "
331+
f"| {arch} "
332+
f"| `{data['flavor']}` "
333+
f"| <details><summary>{summary_text}</summary><br>{details_content}</details> "
334+
f"| <details><summary>Download</summary><br>{download_link}</details> "
335+
"|\n")
336+
337+
return output
338+
339+
340+
def generate_detailed_format(grouped_data):
341+
"""
342+
Generate the old detailed format with YAML
343+
"""
344+
output = ""
345+
346+
for variant in IMAGE_IDS_VARIANT_ORDER:
347+
if variant not in grouped_data:
348+
continue
349+
350+
output += (
351+
f"<details>\n<summary>Variant - {IMAGE_IDS_VARIANT_NAMES[variant]}</summary>\n\n"
352+
)
353+
output += f"### Variant - {IMAGE_IDS_VARIANT_NAMES[variant]}\n\n"
354+
355+
for platform in sorted(grouped_data[variant].keys()):
356+
platform_long_name = PLATFORMS[platform].full_name()
357+
platform_short_name = PLATFORMS[platform].short_name().upper()
358+
output += f"<details>\n<summary>{platform_short_name} - {platform_long_name}</summary>\n\n"
359+
output += f"#### {platform_short_name} - {platform_long_name}\n\n"
360+
361+
for arch in sorted(grouped_data[variant][platform].keys()):
362+
output += f"<details>\n<summary>{arch}</summary>\n\n"
363+
output += f"##### {arch}\n\n"
364+
output += "```\n"
365+
366+
# Process all metadata for this variant/platform/architecture
367+
for metadata in grouped_data[variant][platform][arch]:
368+
data = PLATFORMS[platform].published_images_by_regions(metadata)
369+
if data is None:
370+
continue
371+
372+
output += f"- flavor: {data['flavor']}\n"
373+
374+
download_url = PLATFORMS[platform].artifact_for_flavor(data['flavor'], markdown_format=False)
375+
output += f" download_url: {download_url}\n"
376+
377+
if "regions" in data:
378+
output += " regions:\n"
379+
for region in data["regions"]:
380+
if "image_name" in region:
381+
output += f" - region: {region['region']}\n"
382+
output += f" image_id: {region['image_id']}\n"
383+
output += f" image_name: {region['image_name']}\n"
384+
else:
385+
output += f" - region: {region['region']}\n"
386+
output += f" image_id: {region['image_id']}\n"
387+
elif "details" in data and platform != "gcp":
388+
output += " details:\n"
389+
for key, value in data["details"].items():
390+
output += f" {key}: {value}\n"
391+
elif platform == "gcp" and "details" in data:
392+
# For GCP, move details up to same level as flavor
393+
for key, value in data["details"].items():
394+
output += f" {key}: {value}\n"
395+
elif "gallery_images" in data or "marketplace_images" in data:
396+
if data.get("gallery_images"):
397+
output += " gallery_images:\n"
398+
for img in data["gallery_images"]:
399+
output += f" - hyper_v_generation: {img['hyper_v_generation']}\n"
400+
output += f" azure_cloud: {img['azure_cloud']}\n"
401+
output += f" image_id: {img['image_id']}\n"
402+
if data.get("marketplace_images"):
403+
output += " marketplace_images:\n"
404+
for img in data["marketplace_images"]:
405+
output += f" - hyper_v_generation: {img['hyper_v_generation']}\n"
406+
output += f" urn: {img['urn']}\n"
407+
408+
output += "```\n\n"
409+
output += "</details>\n\n"
410+
411+
output += "</details>\n\n"
412+
413+
output += "</details>\n\n"
414+
415+
return output
416+
417+
418+
def release_notes_image_ids_section(metadata_files):
419+
"""
420+
Groups metadata files by image variant, then platform, then architecture
421+
"""
422+
# Group metadata by variant, platform, and architecture
423+
grouped_data = {}
424+
425+
for metadata_file_path in metadata_files:
426+
with open(metadata_file_path) as f:
427+
metadata = yaml.load(f, Loader=SafeLoader)
428+
429+
published_image_metadata = metadata["published_image_metadata"]
430+
# Skip if no publishing metadata found
431+
if published_image_metadata is None:
432+
continue
433+
434+
platform = metadata["platform"]
435+
arch = metadata["architecture"]
436+
437+
# Determine variant from flavor name
438+
flavor_name = metadata["s3_key"].split("/")[-1]
439+
variant = get_variant_from_flavor(flavor_name)
440+
441+
if variant not in grouped_data:
442+
grouped_data[variant] = {}
443+
if platform not in grouped_data[variant]:
444+
grouped_data[variant][platform] = {}
445+
if arch not in grouped_data[variant][platform]:
446+
grouped_data[variant][platform][arch] = []
447+
448+
grouped_data[variant][platform][arch].append(metadata)
449+
450+
output = "## Published Images\n\n"
451+
452+
output += "<details>\n<summary>📊 Table View</summary>\n\n"
453+
output += generate_table_format(grouped_data)
454+
output += "\n</details>\n\n"
455+
456+
# Old format
457+
output += "<details>\n<summary>📝 Detailed View</summary>\n\n"
458+
output += generate_detailed_format(grouped_data)
459+
output += "\n</details>\n\n"
460+
461+
return output

tests/constants.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,59 @@
2929

3030
RELEASE_NOTES_TEST_DATA_DIR = Path(os.path.dirname(__file__)) / ".." / "test-data" / "release_notes"
3131
RELEASE_NOTES_S3_ARTIFACTS_DIR = RELEASE_NOTES_TEST_DATA_DIR / "s3_bucket_artifacts"
32+
33+
RELEASE_ARTIFACTS_METADATA_FILES = [
34+
"ali-gardener_prod-amd64.s3_metadata.yaml",
35+
"aws-gardener_prod-amd64.s3_metadata.yaml",
36+
"aws-gardener_prod-arm64.s3_metadata.yaml",
37+
"aws-gardener_prod_tpm2_trustedboot-amd64.s3_metadata.yaml",
38+
"aws-gardener_prod_tpm2_trustedboot-arm64.s3_metadata.yaml",
39+
"aws-gardener_prod_usi-amd64.s3_metadata.yaml",
40+
"aws-gardener_prod_usi-arm64.s3_metadata.yaml",
41+
"azure-gardener_prod-amd64.s3_metadata.yaml",
42+
"azure-gardener_prod-arm64.s3_metadata.yaml",
43+
"azure-gardener_prod_tpm2_trustedboot-amd64.s3_metadata.yaml",
44+
"azure-gardener_prod_tpm2_trustedboot-arm64.s3_metadata.yaml",
45+
"azure-gardener_prod_usi-amd64.s3_metadata.yaml",
46+
"azure-gardener_prod_usi-arm64.s3_metadata.yaml",
47+
"container-amd64.s3_metadata.yaml",
48+
"container-arm64.s3_metadata.yaml",
49+
"gcp-gardener_prod-amd64.s3_metadata.yaml",
50+
"gcp-gardener_prod-arm64.s3_metadata.yaml",
51+
"gcp-gardener_prod_tpm2_trustedboot-amd64.s3_metadata.yaml",
52+
"gcp-gardener_prod_tpm2_trustedboot-arm64.s3_metadata.yaml",
53+
"gcp-gardener_prod_usi-amd64.s3_metadata.yaml",
54+
"gcp-gardener_prod_usi-arm64.s3_metadata.yaml",
55+
"gdch-gardener_prod-amd64.s3_metadata.yaml",
56+
"gdch-gardener_prod-arm64.s3_metadata.yaml",
57+
"kvm-gardener_prod-amd64.s3_metadata.yaml",
58+
"kvm-gardener_prod-arm64.s3_metadata.yaml",
59+
"kvm-gardener_prod_tpm2_trustedboot-amd64.s3_metadata.yaml",
60+
"kvm-gardener_prod_tpm2_trustedboot-arm64.s3_metadata.yaml",
61+
"kvm-gardener_prod_usi-amd64.s3_metadata.yaml",
62+
"kvm-gardener_prod_usi-arm64.s3_metadata.yaml",
63+
"metal-capi-amd64.s3_metadata.yaml",
64+
"metal-capi-arm64.s3_metadata.yaml",
65+
"metal-gardener_prod-amd64.s3_metadata.yaml",
66+
"metal-gardener_prod-arm64.s3_metadata.yaml",
67+
"metal-gardener_prod_tpm2_trustedboot-amd64.s3_metadata.yaml",
68+
"metal-gardener_prod_tpm2_trustedboot-arm64.s3_metadata.yaml",
69+
"metal-gardener_prod_usi-amd64.s3_metadata.yaml",
70+
"metal-gardener_prod_usi-arm64.s3_metadata.yaml",
71+
"metal-gardener_pxe-amd64.s3_metadata.yaml",
72+
"metal-gardener_pxe-arm64.s3_metadata.yaml",
73+
"metal_pxe-amd64.s3_metadata.yaml",
74+
"metal_pxe-arm64.s3_metadata.yaml",
75+
"metal-vhost-amd64.s3_metadata.yaml",
76+
"metal-vhost-arm64.s3_metadata.yaml",
77+
"openstackbaremetal-gardener_prod-amd64.s3_metadata.yaml",
78+
"openstackbaremetal-gardener_prod-arm64.s3_metadata.yaml",
79+
"openstack-gardener_prod-amd64.s3_metadata.yaml",
80+
"openstack-gardener_prod-arm64.s3_metadata.yaml",
81+
"openstack-gardener_prod_tpm2_trustedboot-amd64.s3_metadata.yaml",
82+
"openstack-gardener_prod_tpm2_trustedboot-arm64.s3_metadata.yaml",
83+
"openstack-gardener_prod_usi-amd64.s3_metadata.yaml",
84+
"openstack-gardener_prod_usi-arm64.s3_metadata.yaml",
85+
"vmware-gardener_prod-amd64.s3_metadata.yaml",
86+
"vmware-gardener_prod-arm64.s3_metadata.yaml"
87+
]

tests/github/test_create_github_release_notes.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from gardenlinux.github.release_notes.helpers import get_variant_from_flavor
1313

1414
from ..constants import (
15+
RELEASE_ARTIFACTS_METADATA_FILES,
1516
RELEASE_NOTES_S3_ARTIFACTS_DIR,
1617
RELEASE_NOTES_TEST_DATA_DIR,
1718
TEST_GARDENLINUX_COMMIT,
@@ -126,11 +127,11 @@ def __new__(cls, *args, **kwargs):
126127
glvd_response_fixture_path = RELEASE_NOTES_TEST_DATA_DIR / f"glvd_{TEST_GARDENLINUX_RELEASE}.json"
127128

128129
with requests_mock.Mocker(real_http=True) as m:
129-
for yaml_file in RELEASE_NOTES_S3_ARTIFACTS_DIR.glob("*.yaml"):
130-
filename = yaml_file.name
131-
base = filename[:-len(".s3_metadata.yaml")]
130+
for yaml_file in RELEASE_ARTIFACTS_METADATA_FILES:
131+
filepath = f"{RELEASE_NOTES_S3_ARTIFACTS_DIR}/{yaml_file}"
132+
base = yaml_file[:-len(".s3_metadata.yaml")]
132133
key = f"meta/singles/{base}-{TEST_GARDENLINUX_RELEASE}-{TEST_GARDENLINUX_COMMIT}"
133-
release_s3_bucket.upload_file(str(yaml_file), key)
134+
release_s3_bucket.upload_file(filepath, key)
134135

135136
m.get(
136137
f"{GLVD_BASE_URL}/patchReleaseNotes/{TEST_GARDENLINUX_RELEASE}",

0 commit comments

Comments
 (0)