Skip to content

Commit 7e6c444

Browse files
authored
Adding SRPM duplicates check. (#13315)
1 parent 5b528da commit 7e6c444

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
# This action checks that the specs in this repo
5+
# generate SRPMs with unique names.
6+
name: SRPMs duplicates check
7+
8+
on:
9+
push:
10+
branches: [main, 2.0*, 3.0*, fasttrack/*]
11+
pull_request:
12+
branches: [main, 2.0*, 3.0*, fasttrack/*]
13+
14+
jobs:
15+
check:
16+
name: SRPMs duplicates check
17+
runs-on: ubuntu-latest
18+
strategy:
19+
matrix:
20+
# Each group is published to a different repo, thus we only need to check
21+
# for SRPM duplicates within the group.
22+
specs-dirs-groups: ["SPECS SPECS-SIGNED", "SPECS-EXTENDED"]
23+
24+
steps:
25+
# Checkout the branch of our repo that triggered this action
26+
- name: Workflow trigger checkout
27+
uses: actions/checkout@v4
28+
29+
# For consistency, we use the same major/minor version of Python that Azure Linux ships
30+
- name: Setup Python 3.9
31+
uses: actions/setup-python@v5
32+
with:
33+
python-version: 3.9
34+
35+
- name: Switch to stable toolkit
36+
run: git fetch --all && git checkout 2.0-stable -- toolkit
37+
38+
# Generate the specs.json files. They are the input for the duplicates check script.
39+
- name: Generate specs.json
40+
run: |
41+
set -euo pipefail
42+
43+
for spec_folder in ${{ matrix.specs-dirs-groups }}; do
44+
echo "Generating specs.json for spec folder '$spec_folder'."
45+
46+
sudo make -C toolkit -j$(nproc) parse-specs REBUILD_TOOLS=y SPECS_DIR=../$spec_folder
47+
cp -v build/pkg_artifacts/specs.json ${spec_folder}_specs.json
48+
done
49+
50+
- name: Check for duplicate SRPMs
51+
run: python3 toolkit/scripts/check_srpm_duplicates.py *_specs.json
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Microsoft Corporation.
3+
# Licensed under the MIT License.
4+
5+
import argparse
6+
import json
7+
import os
8+
import sys
9+
from collections import defaultdict
10+
11+
_REPO_KEY = "Repo"
12+
_SPEC_PATH_KEY = "SpecPath"
13+
_SRPM_PATH_KEY = "SrpmPath"
14+
15+
16+
def find_srpm_duplicates(specs_file_paths: list[str]) -> list[tuple[str, set[str]]]:
17+
"""
18+
Analyze multiple specs JSON files to find specs producing the same SRPM.
19+
"""
20+
srpm_to_specs = defaultdict(set)
21+
22+
for specs_file_path in specs_file_paths:
23+
with open(specs_file_path, "r") as f:
24+
data = json.load(f)
25+
26+
if _REPO_KEY not in data:
27+
raise ValueError(
28+
f"Invalid JSON format in {specs_file_path}. Expected '{_REPO_KEY}' key."
29+
)
30+
31+
# Process each item in the repo
32+
for item in data["Repo"]:
33+
if _SRPM_PATH_KEY not in item or _SPEC_PATH_KEY not in item:
34+
raise ValueError(
35+
f"Invalid JSON format in {specs_file_path}. Expected '{_SPEC_PATH_KEY}' and '{_SRPM_PATH_KEY}' keys in each element of '{_REPO_KEY}'."
36+
)
37+
38+
srpm = os.path.basename(item[_SRPM_PATH_KEY])
39+
srpm_to_specs[srpm].add(item[_SPEC_PATH_KEY])
40+
41+
return [
42+
(srpm, specs_paths)
43+
for srpm, specs_paths in srpm_to_specs.items()
44+
if len(specs_paths) > 1
45+
]
46+
47+
48+
if __name__ == "__main__":
49+
parser = argparse.ArgumentParser()
50+
parser.add_argument(
51+
"specs_file_paths",
52+
nargs="+",
53+
help="Paths to the specs JSON files to analyze.",
54+
)
55+
args = parser.parse_args()
56+
57+
srpm_duplicates = find_srpm_duplicates(args.specs_file_paths)
58+
if srpm_duplicates:
59+
print("Error: detected specs building the same SRPM.", file=sys.stderr)
60+
for srpm, specs_paths in srpm_duplicates:
61+
print(f"{srpm}:", file=sys.stderr)
62+
for spec_path in specs_paths:
63+
print(f" - {spec_path}", file=sys.stderr)
64+
print(file=sys.stderr)
65+
sys.exit(1)
66+
67+
print("No SRPM duplicates found.")

0 commit comments

Comments
 (0)